From: David Schleef Date: Tue, 14 Sep 2010 01:49:43 +0000 (-0700) Subject: [MOVED FROM BAD 32/68] colorspace: Add conversion code X-Git-Tag: 1.19.3~511^2~7526 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b045ad22167fdf669a67659e484effe311522fef;p=platform%2Fupstream%2Fgstreamer.git [MOVED FROM BAD 32/68] colorspace: Add conversion code Work in progress. Colorspace handles most format conversion using 3-stage getline/matrix/putline process using an AYUV or ARGB intermediate, with most functions handled by Orc. There is also a table of single-pass conversions, all handled by Orc. The plan is to add optional stages for various chroma upsampling/downsampling algorithms, dithering, and float/int16 intermediates, and then have Orc create multi-stage functions at runtime. --- diff --git a/gst/colorspace/Makefile.am b/gst/colorspace/Makefile.am index e011bb9..a297f31 100644 --- a/gst/colorspace/Makefile.am +++ b/gst/colorspace/Makefile.am @@ -3,7 +3,7 @@ plugin_LTLIBRARIES = libgstcolorspace.la ORC_SOURCE=gstcolorspaceorc include $(top_srcdir)/common/orc.mak -libgstcolorspace_la_SOURCES = gstcolorspace.c +libgstcolorspace_la_SOURCES = gstcolorspace.c colorspace.c nodist_libgstcolorspace_la_SOURCES = $(ORC_NODIST_SOURCES) libgstcolorspace_la_CFLAGS = \ $(GST_PLUGINS_BASE_CFLAGS) \ @@ -17,6 +17,6 @@ libgstcolorspace_la_LIBADD = \ libgstcolorspace_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstcolorspace_la_LIBTOOLFLAGS = --tag=disable-static -noinst_HEADERS = gstcolorspace.h +noinst_HEADERS = gstcolorspace.h colorspace.h diff --git a/gst/colorspace/colorspace.c b/gst/colorspace/colorspace.c new file mode 100644 index 0000000..af6c7f2 --- /dev/null +++ b/gst/colorspace/colorspace.c @@ -0,0 +1,1240 @@ +/* GStreamer + * Copyright (C) 2010 David Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "colorspace.h" +#include +#include +#include "gstcolorspaceorc.h" + + +static void colorspace_convert_generic (ColorspaceConvert * convert, + guint8 * dest, guint8 * src); +static void colorspace_convert_lookup_fastpath (ColorspaceConvert * convert); +static void colorspace_convert_lookup_getput (ColorspaceConvert * convert); + + +ColorspaceConvert * +colorspace_convert_new (GstVideoFormat to_format, + GstVideoFormat from_format, int width, int height) +{ + ColorspaceConvert *convert; + int i; + + convert = g_malloc (sizeof (ColorspaceConvert)); + memset (convert, 0, sizeof (ColorspaceConvert)); + + convert->to_format = to_format; + convert->from_format = from_format; + convert->height = height; + convert->width = width; + convert->convert = colorspace_convert_generic; + + for (i = 0; i < 4; i++) { + convert->dest_stride[i] = gst_video_format_get_row_stride (to_format, i, + width); + convert->dest_offset[i] = gst_video_format_get_component_offset (to_format, + i, width, height); + if (i == 0) + convert->dest_offset[i] = 0; + + convert->src_stride[i] = gst_video_format_get_row_stride (from_format, i, + width); + convert->src_offset[i] = gst_video_format_get_component_offset (from_format, + i, width, height); + if (i == 0) + convert->src_offset[i] = 0; + + GST_DEBUG ("%d: dest %d %d src %d %d", i, + convert->dest_stride[i], convert->dest_offset[i], + convert->src_stride[i], convert->src_offset[i]); + } + + colorspace_convert_lookup_fastpath (convert); + colorspace_convert_lookup_getput (convert); + + convert->tmpline = g_malloc (sizeof (guint32) * width * 2); + + return convert; +} + +void +colorspace_convert_free (ColorspaceConvert * convert) +{ + if (convert->palette) + g_free (convert->palette); + if (convert->tmpline) + g_free (convert->tmpline); + + g_free (convert); +} + +void +colorspace_convert_set_interlaced (ColorspaceConvert * convert, + gboolean interlaced) +{ + convert->interlaced = interlaced; +} + +void +colorspace_convert_set_palette (ColorspaceConvert * convert, guint32 * palette) +{ + if (convert->palette == NULL) { + convert->palette = g_malloc (sizeof (guint32) * 256); + } + memcpy (convert->palette, palette, sizeof (guint32) * 256); +} + +void +colorspace_convert_convert (ColorspaceConvert * convert, + guint8 * dest, guint8 * src) +{ + convert->convert (convert, dest, src); +} + +/* Line conversion to AYUV */ + +#define FRAME_GET_LINE(dir, comp, line) \ + ((dir) + convert-> dir ## _offset[(comp)] + convert-> dir ## _stride[(comp)] * (line)) + +static void +getline_I420 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_getline_I420 (dest, + FRAME_GET_LINE (src, 0, j), + FRAME_GET_LINE (src, 1, j >> 1), + FRAME_GET_LINE (src, 2, j >> 1), convert->width); +} + +static void +putline_I420 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_putline_I420 (FRAME_GET_LINE (dest, 0, j), + FRAME_GET_LINE (dest, 1, j >> 1), + FRAME_GET_LINE (dest, 2, j >> 1), src, convert->width / 2); +} + +static void +getline_YV12 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_getline_I420 (dest, + FRAME_GET_LINE (src, 0, j), + FRAME_GET_LINE (src, 1, j >> 1), + FRAME_GET_LINE (src, 2, j >> 1), convert->width); +} + +static void +putline_YV12 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_putline_I420 (FRAME_GET_LINE (dest, 0, j), + FRAME_GET_LINE (dest, 1, j >> 1), + FRAME_GET_LINE (dest, 2, j >> 1), src, convert->width / 2); +} + +static void +getline_YUY2 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_getline_YUY2 (dest, FRAME_GET_LINE (src, 0, j), convert->width / 2); +} + +static void +putline_YUY2 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_putline_YUY2 (FRAME_GET_LINE (dest, 0, j), src, convert->width / 2); +} + +static void +getline_UYVY (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_getline_UYVY (dest, FRAME_GET_LINE (src, 0, j), convert->width / 2); +} + +static void +putline_UYVY (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_putline_UYVY (FRAME_GET_LINE (dest, 0, j), src, convert->width / 2); +} + +static void +getline_YVYU (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_getline_YVYU (dest, FRAME_GET_LINE (src, 0, j), convert->width / 2); +} + +static void +putline_YVYU (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_putline_YVYU (FRAME_GET_LINE (dest, 0, j), src, convert->width / 2); +} + +static void +getline_v308 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + int i; + guint8 *srcline = FRAME_GET_LINE (src, 0, j); + for (i = 0; i < convert->width; i++) { + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 1] = srcline[i * 3 + 0]; + dest[i * 4 + 2] = srcline[i * 3 + 1]; + dest[i * 4 + 3] = srcline[i * 3 + 2]; + } +} + +static void +putline_v308 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + int i; + guint8 *destline = FRAME_GET_LINE (dest, 0, j); + for (i = 0; i < convert->width; i++) { + destline[i * 3 + 0] = src[i * 4 + 1]; + destline[i * 3 + 1] = src[i * 4 + 2]; + destline[i * 3 + 2] = src[i * 4 + 3]; + } +} + +static void +getline_AYUV (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + memcpy (dest, FRAME_GET_LINE (src, 0, j), convert->width * 4); +} + +static void +putline_AYUV (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + memcpy (FRAME_GET_LINE (dest, 0, j), src, convert->width * 4); +} + +#if 0 +static void +getline_v410 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + int i; + guint8 *srcline = FRAME_GET_LINE (src, 0, j); + for (i = 0; i < convert->width; i++) { + dest[i * 4 + 0] = GST_READ_UINT16_LE (srcline + i * 8 + 0); + dest[i * 4 + 1] = GST_READ_UINT16_LE (srcline + i * 8 + 2); + dest[i * 4 + 2] = GST_READ_UINT16_LE (srcline + i * 8 + 4); + dest[i * 4 + 3] = GST_READ_UINT16_LE (srcline + i * 8 + 6); + } +} +#endif + +static void +getline_v210 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + int i; + guint8 *srcline = FRAME_GET_LINE (src, 0, j); + + for (i = 0; i < convert->width; i += 6) { + guint32 a0, a1, a2, a3; + guint16 y0, y1, y2, y3, y4, y5; + guint16 u0, u2, u4; + guint16 v0, v2, v4; + + a0 = GST_READ_UINT32_LE (srcline + (i / 6) * 16 + 0); + a1 = GST_READ_UINT32_LE (srcline + (i / 6) * 16 + 4); + a2 = GST_READ_UINT32_LE (srcline + (i / 6) * 16 + 8); + a3 = GST_READ_UINT32_LE (srcline + (i / 6) * 16 + 12); + + u0 = ((a0 >> 0) & 0x3ff) >> 2; + y0 = ((a0 >> 10) & 0x3ff) >> 2; + v0 = ((a0 >> 20) & 0x3ff) >> 2; + y1 = ((a1 >> 0) & 0x3ff) >> 2; + + u2 = ((a1 >> 10) & 0x3ff) >> 2; + y2 = ((a1 >> 20) & 0x3ff) >> 2; + v2 = ((a2 >> 0) & 0x3ff) >> 2; + y3 = ((a2 >> 10) & 0x3ff) >> 2; + + u4 = ((a2 >> 20) & 0x3ff) >> 2; + y4 = ((a3 >> 0) & 0x3ff) >> 2; + v4 = ((a3 >> 10) & 0x3ff) >> 2; + y5 = ((a3 >> 20) & 0x3ff) >> 2; + + dest[4 * (i + 0) + 0] = 0xff; + dest[4 * (i + 0) + 1] = y0; + dest[4 * (i + 0) + 2] = u0; + dest[4 * (i + 0) + 3] = v0; + + dest[4 * (i + 1) + 0] = 0xff; + dest[4 * (i + 1) + 1] = y1; + dest[4 * (i + 1) + 2] = u0; + dest[4 * (i + 1) + 3] = v0; + + dest[4 * (i + 2) + 0] = 0xff; + dest[4 * (i + 2) + 1] = y2; + dest[4 * (i + 2) + 2] = u2; + dest[4 * (i + 2) + 3] = v2; + + dest[4 * (i + 3) + 0] = 0xff; + dest[4 * (i + 3) + 1] = y3; + dest[4 * (i + 3) + 2] = u2; + dest[4 * (i + 3) + 3] = v2; + + dest[4 * (i + 4) + 0] = 0xff; + dest[4 * (i + 4) + 1] = y4; + dest[4 * (i + 4) + 2] = u4; + dest[4 * (i + 4) + 3] = v4; + + dest[4 * (i + 5) + 0] = 0xff; + dest[4 * (i + 5) + 1] = y5; + dest[4 * (i + 5) + 2] = u4; + dest[4 * (i + 5) + 3] = v4; + + } + +} + +static void +putline_v210 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + int i; + guint8 *destline = FRAME_GET_LINE (dest, 0, j); + + for (i = 0; i < convert->width + 5; i += 6) { + guint32 a0, a1, a2, a3; + guint16 y0, y1, y2, y3, y4, y5; + guint16 u0, u1, u2; + guint16 v0, v1, v2; + + y0 = src[4 * (i + 0) + 1]; + y1 = src[4 * (i + 1) + 1]; + y2 = src[4 * (i + 2) + 1]; + y3 = src[4 * (i + 3) + 1]; + y4 = src[4 * (i + 4) + 1]; + y5 = src[4 * (i + 5) + 1]; + + u0 = (src[4 * (i + 0) + 2] + src[4 * (i + 1) + 2] + 1) >> 1; + u1 = (src[4 * (i + 2) + 2] + src[4 * (i + 3) + 2] + 1) >> 1; + u2 = (src[4 * (i + 4) + 2] + src[4 * (i + 5) + 2] + 1) >> 1; + + v0 = (src[4 * (i + 0) + 3] + src[4 * (i + 1) + 3] + 1) >> 1; + v1 = (src[4 * (i + 2) + 3] + src[4 * (i + 3) + 3] + 1) >> 1; + v2 = (src[4 * (i + 4) + 3] + src[4 * (i + 5) + 3] + 1) >> 1; + + a0 = (u0 << 2) | ((y0 << 2) << 10) | ((v0 << 2) << 20); + a1 = (y1 << 2) | ((u1 << 2) << 10) | ((y2 << 2) << 20); + a2 = (v1 << 2) | ((y3 << 2) << 10) | ((u2 << 2) << 20); + a3 = (y4 << 2) | ((v2 << 2) << 10) | ((y5 << 2) << 20); + + GST_WRITE_UINT32_LE (destline + (i / 6) * 16 + 0, a0); + GST_WRITE_UINT32_LE (destline + (i / 6) * 16 + 4, a1); + GST_WRITE_UINT32_LE (destline + (i / 6) * 16 + 8, a2); + GST_WRITE_UINT32_LE (destline + (i / 6) * 16 + 12, a3); + } +} + +static void +getline_v216 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + int i; + guint8 *srcline = FRAME_GET_LINE (src, 0, j); + for (i = 0; i < convert->width; i++) { + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 1] = GST_READ_UINT16_LE (srcline + i * 4 + 2); + dest[i * 4 + 2] = GST_READ_UINT16_LE (srcline + (i >> 1) * 8 + 0); + dest[i * 4 + 3] = GST_READ_UINT16_LE (srcline + (i >> 1) * 8 + 4); + } +} + +static void +putline_v216 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + int i; + guint8 *destline = FRAME_GET_LINE (dest, 0, j); + for (i = 0; i < convert->width / 2; i++) { + GST_WRITE_UINT16_LE (destline + i * 8 + 0, src[(i * 2 + 0) * 4 + 2] << 8); + GST_WRITE_UINT16_LE (destline + i * 8 + 2, src[(i * 2 + 0) * 4 + 1] << 8); + GST_WRITE_UINT16_LE (destline + i * 8 + 4, src[(i * 2 + 1) * 4 + 3] << 8); + GST_WRITE_UINT16_LE (destline + i * 8 + 8, src[(i * 2 + 0) * 4 + 1] << 8); + } +} + +static void +getline_Y42B (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_getline_Y42B (dest, + FRAME_GET_LINE (src, 0, j), + FRAME_GET_LINE (src, 1, j), + FRAME_GET_LINE (src, 2, j), convert->width / 2); +} + +static void +putline_Y42B (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_putline_Y42B (FRAME_GET_LINE (dest, 0, j), + FRAME_GET_LINE (dest, 1, j), + FRAME_GET_LINE (dest, 2, j), src, convert->width / 2); +} + +static void +getline_Y444 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_getline_Y444 (dest, + FRAME_GET_LINE (src, 0, j), + FRAME_GET_LINE (src, 1, j), FRAME_GET_LINE (src, 2, j), convert->width); +} + +static void +putline_Y444 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_putline_Y444 (FRAME_GET_LINE (dest, 0, j), + FRAME_GET_LINE (dest, 1, j), + FRAME_GET_LINE (dest, 2, j), src, convert->width); +} + +static void +getline_Y800 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_getline_Y800 (dest, FRAME_GET_LINE (src, 0, j), convert->width); +} + +static void +putline_Y800 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_putline_Y800 (FRAME_GET_LINE (dest, 0, j), src, convert->width); +} + +static void +getline_BGRA (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_getline_BGRA (dest, FRAME_GET_LINE (src, 0, j), convert->width); +} + +static void +putline_BGRA (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_putline_BGRA (FRAME_GET_LINE (dest, 0, j), src, convert->width); +} + +static void +getline_ABGR (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_getline_ABGR (dest, FRAME_GET_LINE (src, 0, j), convert->width); +} + +static void +putline_ABGR (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_putline_ABGR (FRAME_GET_LINE (dest, 0, j), src, convert->width); +} + +static void +getline_RGBA (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_getline_RGBA (dest, FRAME_GET_LINE (src, 0, j), convert->width); +} + +static void +putline_RGBA (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_putline_RGBA (FRAME_GET_LINE (dest, 0, j), src, convert->width); +} + +static void +getline_RGB (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + int i; + guint8 *srcline = FRAME_GET_LINE (src, 0, j); + for (i = 0; i < convert->width; i++) { + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 1] = srcline[i * 3 + 0]; + dest[i * 4 + 2] = srcline[i * 3 + 1]; + dest[i * 4 + 3] = srcline[i * 3 + 2]; + } +} + +static void +putline_RGB (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + int i; + guint8 *destline = FRAME_GET_LINE (dest, 0, j); + for (i = 0; i < convert->width; i++) { + destline[i * 3 + 0] = src[i * 4 + 1]; + destline[i * 3 + 1] = src[i * 4 + 2]; + destline[i * 3 + 2] = src[i * 4 + 3]; + } +} + +static void +getline_BGR (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + int i; + guint8 *srcline = FRAME_GET_LINE (src, 0, j); + for (i = 0; i < convert->width; i++) { + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 1] = srcline[i * 3 + 2]; + dest[i * 4 + 2] = srcline[i * 3 + 1]; + dest[i * 4 + 3] = srcline[i * 3 + 0]; + } +} + +static void +putline_BGR (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + int i; + guint8 *destline = FRAME_GET_LINE (dest, 0, j); + for (i = 0; i < convert->width; i++) { + destline[i * 3 + 0] = src[i * 4 + 3]; + destline[i * 3 + 1] = src[i * 4 + 2]; + destline[i * 3 + 2] = src[i * 4 + 1]; + } +} + +static void +getline_NV12 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_getline_NV12 (dest, + FRAME_GET_LINE (src, 0, j), + FRAME_GET_LINE (src, 1, j >> 1), convert->width / 2); +} + +static void +putline_NV12 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_putline_NV12 (FRAME_GET_LINE (dest, 0, j), + FRAME_GET_LINE (dest, 1, j >> 1), src, convert->width / 2); +} + +static void +getline_NV21 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_getline_NV21 (dest, + FRAME_GET_LINE (src, 0, j), + FRAME_GET_LINE (src, 2, j >> 1), convert->width / 2); +} + +static void +putline_NV21 (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + cogorc_putline_NV21 (FRAME_GET_LINE (dest, 0, j), + FRAME_GET_LINE (dest, 2, j >> 1), src, convert->width / 2); +} + +static void +getline_UYVP (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + int i; + + for (i = 0; i < convert->width; i += 2) { + guint16 y0, y1; + guint16 u0; + guint16 v0; + + u0 = (src[(i / 2) * 5 + 0] << 2) | (src[(i / 2) * 5 + 1] >> 6); + y0 = ((src[(i / 2) * 5 + 1] & 0x3f) << 4) | (src[(i / 2) * 5 + 2] >> 4); + v0 = ((src[(i / 2) * 5 + 2] & 0x0f) << 6) | (src[(i / 2) * 5 + 3] >> 2); + y1 = ((src[(i / 2) * 5 + 3] & 0x03) << 8) | src[(i / 2) * 5 + 4]; + + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 1] = y0 >> 2; + dest[i * 4 + 2] = u0 >> 2; + dest[i * 4 + 3] = v0 >> 2; + dest[i * 4 + 4] = 0xff; + dest[i * 4 + 5] = y1 >> 2; + dest[i * 4 + 6] = u0 >> 2; + dest[i * 4 + 7] = v0 >> 2; + } +} + +static void +putline_UYVP (ColorspaceConvert * convert, guint8 * dest, guint8 * src, int j) +{ + int i; + + for (i = 0; i < convert->width; i += 2) { + guint16 y0, y1; + guint16 u0; + guint16 v0; + + y0 = src[4 * (i + 0) + 1]; + y1 = src[4 * (i + 1) + 1]; + u0 = (src[4 * (i + 0) + 2] + src[4 * (i + 1) + 2] + 1) >> 1; + v0 = (src[4 * (i + 0) + 3] + src[4 * (i + 1) + 3] + 1) >> 1; + + dest[(i / 2) * 5 + 0] = u0; + dest[(i / 2) * 5 + 1] = y0 >> 2; + dest[(i / 2) * 5 + 2] = (y0 << 6) | (v0 >> 4); + dest[(i / 2) * 5 + 3] = (v0 << 4) | (y1 >> 2); + dest[(i / 2) * 5 + 4] = (y1 << 2); + } +} + + + +typedef struct +{ + GstVideoFormat format; + void (*getline) (ColorspaceConvert * convert, guint8 * dest, guint8 * src, + int j); + void (*putline) (ColorspaceConvert * convert, guint8 * dest, guint8 * src, + int j); +} ColorspaceLine; +static ColorspaceLine lines[] = { + {GST_VIDEO_FORMAT_I420, getline_I420, putline_I420}, + {GST_VIDEO_FORMAT_YV12, getline_YV12, putline_YV12}, + {GST_VIDEO_FORMAT_YUY2, getline_YUY2, putline_YUY2}, + {GST_VIDEO_FORMAT_UYVY, getline_UYVY, putline_UYVY}, + {GST_VIDEO_FORMAT_AYUV, getline_AYUV, putline_AYUV}, + {GST_VIDEO_FORMAT_RGBx, getline_RGBA, putline_RGBA}, + {GST_VIDEO_FORMAT_BGRx, getline_BGRA, putline_BGRA}, + {GST_VIDEO_FORMAT_xRGB, getline_AYUV, putline_AYUV}, + {GST_VIDEO_FORMAT_xBGR, getline_ABGR, putline_ABGR}, + {GST_VIDEO_FORMAT_RGBA, getline_RGBA, putline_RGBA}, + {GST_VIDEO_FORMAT_BGRA, getline_BGRA, putline_BGRA}, + {GST_VIDEO_FORMAT_ARGB, getline_AYUV, putline_AYUV}, + {GST_VIDEO_FORMAT_ABGR, getline_ABGR, putline_ABGR}, + {GST_VIDEO_FORMAT_RGB, getline_RGB, putline_RGB}, + {GST_VIDEO_FORMAT_BGR, getline_BGR, putline_BGR}, + //{GST_VIDEO_FORMAT_Y41B, getline_Y41B, putline_Y41B}, + {GST_VIDEO_FORMAT_Y42B, getline_Y42B, putline_Y42B}, + {GST_VIDEO_FORMAT_YVYU, getline_YVYU, putline_YVYU}, + {GST_VIDEO_FORMAT_Y444, getline_Y444, putline_Y444}, + {GST_VIDEO_FORMAT_v210, getline_v210, putline_v210}, + {GST_VIDEO_FORMAT_v216, getline_v216, putline_v216}, + {GST_VIDEO_FORMAT_NV12, getline_NV12, putline_NV12}, + {GST_VIDEO_FORMAT_NV21, getline_NV21, putline_NV21}, + //{GST_VIDEO_FORMAT_GRAY8, getline_GRAY8, putline_GRAY8}, + //{GST_VIDEO_FORMAT_GRAY16_BE, getline_GRAY16_BE, putline_GRAY16_BE}, + //{GST_VIDEO_FORMAT_GRAY16_LE, getline_GRAY16_LE, putline_GRAY16_LE}, + {GST_VIDEO_FORMAT_v308, getline_v308, putline_v308}, + {GST_VIDEO_FORMAT_Y800, getline_Y800, putline_Y800}, + //{GST_VIDEO_FORMAT_Y16, getline_Y16, putline_Y16}, + //{GST_VIDEO_FORMAT_RGB16, getline_RGB16, putline_RGB16}, + //{GST_VIDEO_FORMAT_BGR16, getline_BGR16, putline_BGR16}, + //{GST_VIDEO_FORMAT_RGB15, getline_RGB15, putline_RGB15}, + //{GST_VIDEO_FORMAT_BGR15, getline_BGR15, putline_BGR15}, + {GST_VIDEO_FORMAT_UYVP, getline_UYVP, putline_UYVP} +}; + + +static void +matrix_rgb2yuv (ColorspaceConvert * convert) +{ + int i; + int r, g, b; + int y, u, v; + guint8 *tmpline = convert->tmpline; + + for (i = 0; i < convert->width; i++) { + r = tmpline[i * 4 + 1]; + g = tmpline[i * 4 + 2]; + b = tmpline[i * 4 + 3]; + + y = (66 * r + 129 * g + 25 * b + 4096) >> 8; + u = (-38 * r - 74 * g + 112 * b + 32768) >> 8; + v = (112 * r - 94 * g - 18 * b + 32768) >> 8; + + tmpline[i * 4 + 1] = CLAMP (y, 0, 255); + tmpline[i * 4 + 2] = CLAMP (u, 0, 255); + tmpline[i * 4 + 3] = CLAMP (v, 0, 255); + } +} + +static void +matrix_yuv2rgb (ColorspaceConvert * convert) +{ + int i; + int r, g, b; + int y, u, v; + guint8 *tmpline = convert->tmpline; + + for (i = 0; i < convert->width; i++) { + y = tmpline[i * 4 + 1]; + u = tmpline[i * 4 + 2]; + v = tmpline[i * 4 + 3]; + + r = (298 * y + 409 * v - 57068) >> 8; + g = (298 * y - 100 * u - 208 * v + 34707) >> 8; + b = (298 * y + 516 * u - 70870) >> 8; + + tmpline[i * 4 + 1] = CLAMP (r, 0, 255); + tmpline[i * 4 + 2] = CLAMP (g, 0, 255); + tmpline[i * 4 + 3] = CLAMP (b, 0, 255); + } +} + +static void +matrix_identity (ColorspaceConvert * convert) +{ + /* do nothing */ +} + + +static void +colorspace_convert_lookup_getput (ColorspaceConvert * convert) +{ + int i; + + convert->getline = NULL; + for (i = 0; i < sizeof (lines) / sizeof (lines[0]); i++) { + if (lines[i].format == convert->from_format) { + convert->getline = lines[i].getline; + break; + } + } + convert->putline = NULL; + for (i = 0; i < sizeof (lines) / sizeof (lines[0]); i++) { + if (lines[i].format == convert->to_format) { + convert->putline = lines[i].putline; + break; + } + } + GST_ERROR ("get %p put %p", convert->getline, convert->putline); + + if (gst_video_format_is_rgb (convert->to_format) && + gst_video_format_is_yuv (convert->from_format)) { + convert->matrix = matrix_yuv2rgb; + } else if (gst_video_format_is_yuv (convert->to_format) && + gst_video_format_is_rgb (convert->from_format)) { + convert->matrix = matrix_rgb2yuv; + } else { + convert->matrix = matrix_identity; + } +} + +static void +colorspace_convert_generic (ColorspaceConvert * convert, guint8 * dest, + guint8 * src) +{ + int j; + + if (convert->getline == NULL) { + GST_ERROR ("no getline"); + return; + } + + if (convert->putline == NULL) { + GST_ERROR ("no putline"); + return; + } + + for (j = 0; j < convert->height; j++) { + convert->getline (convert, convert->tmpline, src, j); + convert->matrix (convert); + convert->putline (convert, dest, convert->tmpline, j); + } +} + + +/* Fast paths */ + +static void +convert_I420_YUY2 (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + int i; + + for (i = 0; i < convert->height; i += 2) { + cogorc_convert_I420_YUY2 (FRAME_GET_LINE (dest, 0, i), + FRAME_GET_LINE (dest, 0, i + 1), + FRAME_GET_LINE (src, 0, i), + FRAME_GET_LINE (src, 0, i + 1), + FRAME_GET_LINE (src, 1, i >> 1), + FRAME_GET_LINE (src, 2, i >> 1), (convert->width + 1) / 2); + cogorc_convert_I420_YUY2 (FRAME_GET_LINE (dest, 0, i), + FRAME_GET_LINE (dest, 0, i + 1), + FRAME_GET_LINE (src, 0, i), + FRAME_GET_LINE (src, 0, i + 1), + FRAME_GET_LINE (src, 1, i >> 1), + FRAME_GET_LINE (src, 2, i >> 1), (convert->width + 1) / 2); + } +} + +static void +convert_I420_UYVY (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + int i; + + for (i = 0; i < convert->height; i += 2) { + cogorc_convert_I420_UYVY (FRAME_GET_LINE (dest, 0, i), + FRAME_GET_LINE (dest, 0, i + 1), + FRAME_GET_LINE (src, 0, i), + FRAME_GET_LINE (src, 0, i + 1), + FRAME_GET_LINE (src, 1, i >> 1), + FRAME_GET_LINE (src, 2, i >> 1), (convert->width + 1) / 2); + } +} + +static void +convert_I420_AYUV (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + int i; + + for (i = 0; i < convert->height; i += 2) { + cogorc_convert_I420_AYUV (FRAME_GET_LINE (dest, 0, i), + FRAME_GET_LINE (dest, 0, i + 1), + FRAME_GET_LINE (src, 0, i), + FRAME_GET_LINE (src, 0, i + 1), + FRAME_GET_LINE (src, 1, i >> 1), + FRAME_GET_LINE (src, 2, i >> 1), convert->width); + } +} + +static void +convert_I420_Y42B (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_memcpy_2d (FRAME_GET_LINE (dest, 0, 0), convert->dest_stride[0], + FRAME_GET_LINE (src, 0, 0), convert->src_stride[0], + convert->width, convert->height); + + cogorc_planar_chroma_420_422 (FRAME_GET_LINE (dest, 1, 0), + 2 * convert->dest_stride[1], FRAME_GET_LINE (dest, 1, 1), + 2 * convert->dest_stride[1], FRAME_GET_LINE (src, 1, 0), + convert->src_stride[1], (convert->width + 1) / 2, convert->height / 2); + + cogorc_planar_chroma_420_422 (FRAME_GET_LINE (dest, 2, 0), + 2 * convert->dest_stride[2], FRAME_GET_LINE (dest, 2, 1), + 2 * convert->dest_stride[2], FRAME_GET_LINE (src, 2, 0), + convert->src_stride[2], (convert->width + 1) / 2, convert->height / 2); +} + +static void +convert_I420_Y444 (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_memcpy_2d (FRAME_GET_LINE (dest, 0, 0), convert->dest_stride[0], + FRAME_GET_LINE (src, 0, 0), convert->src_stride[0], + convert->width, convert->height); + + cogorc_planar_chroma_420_444 (FRAME_GET_LINE (dest, 1, 0), + 2 * convert->dest_stride[1], FRAME_GET_LINE (dest, 1, 1), + 2 * convert->dest_stride[1], FRAME_GET_LINE (src, 1, 0), + convert->src_stride[1], (convert->width + 1) / 2, + (convert->height + 1) / 2); + + cogorc_planar_chroma_420_444 (FRAME_GET_LINE (dest, 2, 0), + 2 * convert->dest_stride[2], FRAME_GET_LINE (dest, 2, 1), + 2 * convert->dest_stride[2], FRAME_GET_LINE (src, 2, 0), + convert->src_stride[2], (convert->width + 1) / 2, + (convert->height + 1) / 2); +} + +static void +convert_YUY2_I420 (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + int i; + + for (i = 0; i < convert->height; i += 2) { + cogorc_convert_YUY2_I420 (FRAME_GET_LINE (dest, 0, i), + FRAME_GET_LINE (dest, 0, i + 1), + FRAME_GET_LINE (dest, 1, i >> 1), + FRAME_GET_LINE (dest, 2, i >> 1), + FRAME_GET_LINE (src, 0, i), + FRAME_GET_LINE (src, 0, i + 1), (convert->width + 1) / 2); + } +} + +static void +convert_YUY2_AYUV (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_YUY2_AYUV (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], (convert->width + 1) / 2, convert->height); +} + +static void +convert_YUY2_Y42B (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_YUY2_Y42B (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (dest, 1, 0), + convert->dest_stride[1], FRAME_GET_LINE (dest, 2, 0), + convert->dest_stride[2], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], (convert->width + 1) / 2, convert->height); +} + +static void +convert_YUY2_Y444 (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_YUY2_Y444 (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (dest, 1, 0), + convert->dest_stride[1], FRAME_GET_LINE (dest, 2, 0), + convert->dest_stride[2], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], (convert->width + 1) / 2, convert->height); +} + + +static void +convert_UYVY_I420 (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + int i; + + for (i = 0; i < convert->height; i += 2) { + cogorc_convert_UYVY_I420 (FRAME_GET_LINE (dest, 0, i), + FRAME_GET_LINE (dest, 0, i + 1), + FRAME_GET_LINE (dest, 1, i >> 1), + FRAME_GET_LINE (dest, 2, i >> 1), + FRAME_GET_LINE (src, 0, i), + FRAME_GET_LINE (src, 0, i + 1), (convert->width + 1) / 2); + } +} + +static void +convert_UYVY_AYUV (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_UYVY_AYUV (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], (convert->width + 1) / 2, convert->height); +} + +static void +convert_UYVY_YUY2 (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_UYVY_YUY2 (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], (convert->width + 1) / 2, convert->height); +} + +static void +convert_UYVY_Y42B (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_UYVY_Y42B (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (dest, 1, 0), + convert->dest_stride[1], FRAME_GET_LINE (dest, 2, 0), + convert->dest_stride[2], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], (convert->width + 1) / 2, convert->height); +} + +static void +convert_UYVY_Y444 (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_UYVY_Y444 (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (dest, 1, 0), + convert->dest_stride[1], FRAME_GET_LINE (dest, 2, 0), + convert->dest_stride[2], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], (convert->width + 1) / 2, convert->height); +} + +static void +convert_AYUV_I420 (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_AYUV_I420 (FRAME_GET_LINE (dest, 0, 0), + 2 * convert->dest_stride[0], FRAME_GET_LINE (dest, 0, 1), + 2 * convert->dest_stride[0], FRAME_GET_LINE (dest, 1, 0), + convert->dest_stride[1], FRAME_GET_LINE (dest, 2, 0), + convert->dest_stride[2], FRAME_GET_LINE (src, 0, 0), + 2 * convert->src_stride[0], FRAME_GET_LINE (src, 0, 1), + 2 * convert->src_stride[0], convert->width / 2, convert->height / 2); +} + +static void +convert_AYUV_YUY2 (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_AYUV_YUY2 (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], convert->width / 2, convert->height); +} + +static void +convert_AYUV_UYVY (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_AYUV_UYVY (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], convert->width / 2, convert->height); +} + +static void +convert_AYUV_Y42B (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_AYUV_Y42B (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (dest, 1, 0), + convert->dest_stride[1], FRAME_GET_LINE (dest, 2, 0), + convert->dest_stride[2], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], (convert->width + 1) / 2, convert->height); +} + +static void +convert_AYUV_Y444 (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_AYUV_Y444 (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (dest, 1, 0), + convert->dest_stride[1], FRAME_GET_LINE (dest, 2, 0), + convert->dest_stride[2], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], convert->width, convert->height); +} + +static void +convert_Y42B_I420 (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_memcpy_2d (FRAME_GET_LINE (dest, 0, 0), convert->dest_stride[0], + FRAME_GET_LINE (src, 0, 0), convert->src_stride[0], + convert->width, convert->height); + + cogorc_planar_chroma_422_420 (FRAME_GET_LINE (dest, 1, 0), + convert->dest_stride[1], FRAME_GET_LINE (src, 1, 0), + 2 * convert->src_stride[1], FRAME_GET_LINE (src, 1, 1), + 2 * convert->src_stride[1], (convert->width + 1) / 2, + (convert->height + 1) / 2); + + cogorc_planar_chroma_422_420 (FRAME_GET_LINE (dest, 2, 0), + convert->dest_stride[2], FRAME_GET_LINE (src, 2, 0), + 2 * convert->src_stride[2], FRAME_GET_LINE (src, 2, 1), + 2 * convert->src_stride[2], (convert->width + 1) / 2, + (convert->height + 1) / 2); +} + +static void +convert_Y42B_Y444 (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_memcpy_2d (FRAME_GET_LINE (dest, 0, 0), convert->dest_stride[0], + FRAME_GET_LINE (src, 0, 0), convert->src_stride[0], + convert->width, convert->height); + + cogorc_planar_chroma_422_444 (FRAME_GET_LINE (dest, 1, 0), + convert->dest_stride[1], FRAME_GET_LINE (src, 1, 0), + convert->src_stride[1], (convert->width + 1) / 2, convert->height); + + cogorc_planar_chroma_422_444 (FRAME_GET_LINE (dest, 2, 0), + convert->dest_stride[2], FRAME_GET_LINE (src, 2, 0), + convert->src_stride[2], (convert->width + 1) / 2, convert->height); +} + +static void +convert_Y42B_YUY2 (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_Y42B_YUY2 (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], FRAME_GET_LINE (src, 1, 0), + convert->src_stride[1], FRAME_GET_LINE (src, 2, 0), + convert->src_stride[2], (convert->width + 1) / 2, convert->height); +} + +static void +convert_Y42B_UYVY (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_Y42B_UYVY (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], FRAME_GET_LINE (src, 1, 0), + convert->src_stride[1], FRAME_GET_LINE (src, 2, 0), + convert->src_stride[2], (convert->width + 1) / 2, convert->height); +} + +static void +convert_Y42B_AYUV (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_Y42B_AYUV (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], FRAME_GET_LINE (src, 1, 0), + convert->src_stride[1], FRAME_GET_LINE (src, 2, 0), + convert->src_stride[2], (convert->width) / 2, convert->height); +} + +static void +convert_Y444_I420 (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_memcpy_2d (FRAME_GET_LINE (dest, 0, 0), convert->dest_stride[0], + FRAME_GET_LINE (src, 0, 0), convert->src_stride[0], + convert->width, convert->height); + + cogorc_planar_chroma_444_420 (FRAME_GET_LINE (dest, 1, 0), + convert->dest_stride[1], FRAME_GET_LINE (src, 1, 0), + 2 * convert->src_stride[1], FRAME_GET_LINE (src, 1, 1), + 2 * convert->src_stride[1], (convert->width + 1) / 2, + (convert->height + 1) / 2); + + cogorc_planar_chroma_444_420 (FRAME_GET_LINE (dest, 2, 0), + convert->dest_stride[2], FRAME_GET_LINE (src, 2, 0), + 2 * convert->src_stride[2], FRAME_GET_LINE (src, 2, 1), + 2 * convert->src_stride[2], (convert->width + 1) / 2, + (convert->height + 1) / 2); +} + +static void +convert_Y444_Y42B (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_memcpy_2d (FRAME_GET_LINE (dest, 0, 0), convert->dest_stride[0], + FRAME_GET_LINE (src, 0, 0), convert->src_stride[0], + convert->width, convert->height); + + cogorc_planar_chroma_444_422 (FRAME_GET_LINE (dest, 1, 0), + convert->dest_stride[1], FRAME_GET_LINE (src, 1, 0), + convert->src_stride[1], (convert->width + 1) / 2, convert->height); + + cogorc_planar_chroma_444_422 (FRAME_GET_LINE (dest, 2, 0), + convert->dest_stride[2], FRAME_GET_LINE (src, 2, 0), + convert->src_stride[2], (convert->width + 1) / 2, convert->height); +} + +static void +convert_Y444_YUY2 (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_Y444_YUY2 (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], FRAME_GET_LINE (src, 1, 0), + convert->src_stride[1], FRAME_GET_LINE (src, 2, 0), + convert->src_stride[2], (convert->width + 1) / 2, convert->height); +} + +static void +convert_Y444_UYVY (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_Y444_UYVY (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], FRAME_GET_LINE (src, 1, 0), + convert->src_stride[1], FRAME_GET_LINE (src, 2, 0), + convert->src_stride[2], (convert->width + 1) / 2, convert->height); +} + +static void +convert_Y444_AYUV (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_Y444_AYUV (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], FRAME_GET_LINE (src, 1, 0), + convert->src_stride[1], FRAME_GET_LINE (src, 2, 0), + convert->src_stride[2], convert->width, convert->height); +} + +static void +convert_AYUV_ARGB (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_AYUV_ARGB (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], convert->width, convert->height); +} + +static void +convert_AYUV_BGRA (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_AYUV_BGRA (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], convert->width, convert->height); +} + +static void +convert_AYUV_ABGR (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_AYUV_ABGR (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], convert->width, convert->height); +} + +static void +convert_AYUV_RGBA (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + cogorc_convert_AYUV_RGBA (FRAME_GET_LINE (dest, 0, 0), + convert->dest_stride[0], FRAME_GET_LINE (src, 0, 0), + convert->src_stride[0], convert->width, convert->height); +} + +static void +convert_I420_BGRA (ColorspaceConvert * convert, guint8 * dest, guint8 * src) +{ + int i; + int quality = 0; + + if (quality > 3) { + for (i = 0; i < convert->height; i++) { + if (i & 1) { + cogorc_convert_I420_BGRA_avg (FRAME_GET_LINE (dest, 0, i), + FRAME_GET_LINE (src, 0, i), + FRAME_GET_LINE (src, 1, i >> 1), + FRAME_GET_LINE (src, 1, (i >> 1) + 1), + FRAME_GET_LINE (src, 2, i >> 1), + FRAME_GET_LINE (src, 2, (i >> 1) + 1), convert->width); + } else { + cogorc_convert_I420_BGRA (FRAME_GET_LINE (dest, 0, i), + FRAME_GET_LINE (src, 0, i), + FRAME_GET_LINE (src, 1, i >> 1), + FRAME_GET_LINE (src, 2, i >> 1), convert->width); + } + } + } else { + for (i = 0; i < convert->height; i++) { + cogorc_convert_I420_BGRA (FRAME_GET_LINE (dest, 0, i), + FRAME_GET_LINE (src, 0, i), + FRAME_GET_LINE (src, 1, i >> 1), + FRAME_GET_LINE (src, 2, i >> 1), convert->width); + } + } +} + + + +/* Fast paths */ + +typedef struct +{ + GstVideoFormat from_format; + GstVideoFormat to_format; + void (*convert) (ColorspaceConvert * convert, guint8 * dest, guint8 * src); +} ColorspaceTransform; +static ColorspaceTransform transforms[] = { + {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_YUY2, convert_I420_YUY2}, + {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_UYVY, convert_I420_UYVY}, + {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_AYUV, convert_I420_AYUV}, + {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_Y42B, convert_I420_Y42B}, + {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_Y444, convert_I420_Y444}, + + {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_FORMAT_I420, convert_YUY2_I420}, + {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_FORMAT_UYVY, convert_UYVY_YUY2}, /* alias */ + {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_FORMAT_AYUV, convert_YUY2_AYUV}, + {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_FORMAT_Y42B, convert_YUY2_Y42B}, + {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_FORMAT_Y444, convert_YUY2_Y444}, + + {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_FORMAT_I420, convert_UYVY_I420}, + {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_FORMAT_YUY2, convert_UYVY_YUY2}, + {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_FORMAT_AYUV, convert_UYVY_AYUV}, + {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_FORMAT_Y42B, convert_UYVY_Y42B}, + {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_FORMAT_Y444, convert_UYVY_Y444}, + + {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_I420, convert_AYUV_I420}, + {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_YUY2, convert_AYUV_YUY2}, + {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_UYVY, convert_AYUV_UYVY}, + {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_Y42B, convert_AYUV_Y42B}, + {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_Y444, convert_AYUV_Y444}, + + {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_I420, convert_Y42B_I420}, + {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_YUY2, convert_Y42B_YUY2}, + {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_UYVY, convert_Y42B_UYVY}, + {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_AYUV, convert_Y42B_AYUV}, + {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_Y444, convert_Y42B_Y444}, + + {GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_I420, convert_Y444_I420}, + {GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_YUY2, convert_Y444_YUY2}, + {GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_UYVY, convert_Y444_UYVY}, + {GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_AYUV, convert_Y444_AYUV}, + {GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_Y42B, convert_Y444_Y42B}, + + {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_ARGB, convert_AYUV_ARGB}, + {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_BGRA, convert_AYUV_BGRA}, + {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_xRGB, convert_AYUV_ARGB}, /* alias */ + {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_BGRx, convert_AYUV_BGRA}, /* alias */ + {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_ABGR, convert_AYUV_ABGR}, + {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_RGBA, convert_AYUV_RGBA}, + {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_xBGR, convert_AYUV_ABGR}, /* alias */ + {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_RGBx, convert_AYUV_RGBA}, /* alias */ + + {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_BGRA, convert_I420_BGRA}, +}; + +static void +colorspace_convert_lookup_fastpath (ColorspaceConvert * convert) +{ + int i; + + for (i = 0; i < sizeof (transforms) / sizeof (transforms[0]); i++) { + if (transforms[i].to_format == convert->to_format && + transforms[i].from_format == convert->from_format) { + convert->convert = transforms[i].convert; + return; + } + } +} diff --git a/gst/colorspace/colorspace.h b/gst/colorspace/colorspace.h new file mode 100644 index 0000000..6add546 --- /dev/null +++ b/gst/colorspace/colorspace.h @@ -0,0 +1,69 @@ +/* Colorspace conversion functions + * Copyright (C) 2010 David Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __COLORSPACE_H__ +#define __COLORSPACE_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _ColorspaceConvert ColorspaceConvert; +typedef struct _ColorspaceFrame ColorspaceComponent; + +struct _ColorspaceComponent { + int offset; + int stride; +}; + +struct _ColorspaceConvert { + gint width, height; + gboolean interlaced; + + GstVideoFormat from_format; + GstVideoFormat to_format; + guint32 *palette; + + guint8 *tmpline; + + int dest_offset[4]; + int dest_stride[4]; + int src_offset[4]; + int src_stride[4]; + + void (*convert) (ColorspaceConvert *convert, guint8 *dest, guint8 *src); + void (*getline) (ColorspaceConvert *convert, guint8 *dest, guint8 *src, int j); + void (*putline) (ColorspaceConvert *convert, guint8 *dest, guint8 *src, int j); + void (*matrix) (ColorspaceConvert *convert); +}; + +ColorspaceConvert * colorspace_convert_new (GstVideoFormat to_format, + GstVideoFormat from_format, int width, int height); +void colorspace_convert_set_interlaced (ColorspaceConvert *convert, + gboolean interlaced); +void colorspace_convert_set_palette (ColorspaceConvert *convert, + guint32 *palette); +void colorspace_convert_free (ColorspaceConvert * convert); +void colorspace_convert_convert (ColorspaceConvert * convert, + guint8 *dest, guint8 *src); + + +G_END_DECLS + +#endif /* __GST_COLORSPACE_H__ */ diff --git a/gst/colorspace/gstcolorspace.c b/gst/colorspace/gstcolorspace.c index 6d1262b..0b70408 100644 --- a/gst/colorspace/gstcolorspace.c +++ b/gst/colorspace/gstcolorspace.c @@ -47,7 +47,7 @@ GST_DEBUG_CATEGORY (colorspace_performance); #define CSP_VIDEO_CAPS \ "video/x-raw-yuv, width = "GST_VIDEO_SIZE_RANGE" , " \ "height="GST_VIDEO_SIZE_RANGE",framerate="GST_VIDEO_FPS_RANGE"," \ - "format= (fourcc) { I420 , NV12 , NV21 , YV12 , YUY2 , Y42B , Y444 , YUV9 , YVU9 , Y41B , Y800 , Y8 , GREY , Y16 , UYVY , YVYU , IYU1 , v308 , AYUV } ;" \ + "format= (fourcc) { I420 , NV12 , NV21 , YV12 , YUY2 , Y42B , Y444 , YUV9 , YVU9 , Y41B , Y800 , Y8 , GREY , Y16 , UYVY , YVYU , IYU1 , v308 , AYUV, v210 } ;" \ GST_VIDEO_CAPS_RGB";" \ GST_VIDEO_CAPS_BGR";" \ GST_VIDEO_CAPS_RGBx";" \ @@ -266,13 +266,23 @@ gst_csp_set_caps (GstBaseTransform * btrans, GstCaps * incaps, in_interlaced != out_interlaced) goto format_mismatch; + space->from_format = in_format; + space->to_format = out_format; space->width = in_width; space->height = in_height; space->interlaced = in_interlaced; + space->convert = colorspace_convert_new (out_format, in_format, + in_width, in_height); + if (space->convert) { + colorspace_convert_set_interlaced (space->convert, in_interlaced); + } /* palette, only for from data */ /* FIXME add palette handling */ +#if 0 + colorspace_convert_set_palette (convert, palette); +#endif GST_DEBUG ("reconfigured %d %d", space->from_format, space->to_format); @@ -281,21 +291,21 @@ gst_csp_set_caps (GstBaseTransform * btrans, GstCaps * incaps, /* ERRORS */ no_width_height: { - GST_DEBUG_OBJECT (space, "did not specify width or height"); + GST_ERROR_OBJECT (space, "did not specify width or height"); space->from_format = GST_VIDEO_FORMAT_UNKNOWN; space->to_format = GST_VIDEO_FORMAT_UNKNOWN; return FALSE; } no_framerate: { - GST_DEBUG_OBJECT (space, "did not specify framerate"); + GST_ERROR_OBJECT (space, "did not specify framerate"); space->from_format = GST_VIDEO_FORMAT_UNKNOWN; space->to_format = GST_VIDEO_FORMAT_UNKNOWN; return FALSE; } format_mismatch: { - GST_DEBUG_OBJECT (space, "input and output formats do not match"); + GST_ERROR_OBJECT (space, "input and output formats do not match"); space->from_format = GST_VIDEO_FORMAT_UNKNOWN; space->to_format = GST_VIDEO_FORMAT_UNKNOWN; return FALSE; @@ -393,6 +403,8 @@ gst_csp_transform (GstBaseTransform * btrans, GstBuffer * inbuf, space->to_format == GST_VIDEO_FORMAT_UNKNOWN)) goto unknown_format; + colorspace_convert_convert (space->convert, GST_BUFFER_DATA (outbuf), + GST_BUFFER_DATA (inbuf)); /* baseclass copies timestamps */ GST_DEBUG ("from %d -> to %d done", space->from_format, space->to_format); diff --git a/gst/colorspace/gstcolorspace.h b/gst/colorspace/gstcolorspace.h index c4bce92..809704f 100644 --- a/gst/colorspace/gstcolorspace.h +++ b/gst/colorspace/gstcolorspace.h @@ -25,6 +25,7 @@ #include #include #include +#include "colorspace.h" G_BEGIN_DECLS @@ -52,6 +53,8 @@ struct _GstCsp { GstVideoFormat from_format; GstVideoFormat to_format; guint32 *palette; + + ColorspaceConvert *convert; }; struct _GstCspClass diff --git a/gst/colorspace/gstcolorspaceorc.orc b/gst/colorspace/gstcolorspaceorc.orc index 6d8fdfd..df6773b 100644 --- a/gst/colorspace/gstcolorspaceorc.orc +++ b/gst/colorspace/gstcolorspaceorc.orc @@ -1,23 +1,23 @@ .function cogorc_memcpy_2d .flags 2d -.dest 1 d1 -.source 1 s1 +.dest 1 d1 guint8 +.source 1 s1 guint8 copyb d1, s1 .function cogorc_downsample_horiz_cosite_1tap -.dest 1 d1 -.source 2 s1 +.dest 1 d1 guint8 +.source 2 s1 guint8 select0wb d1, s1 .function cogorc_downsample_horiz_cosite_3tap -.dest 1 d1 -.source 2 s1 -.source 2 s2 +.dest 1 d1 guint8 +.source 2 s1 guint8 +.source 2 s2 guint8 .temp 1 t1 .temp 1 t2 .temp 1 t3 @@ -41,9 +41,9 @@ convsuswb d1, t4 .function cogorc_downsample_420_jpeg -.dest 1 d1 -.source 2 s1 -.source 2 s2 +.dest 1 d1 guint8 +.source 2 s1 guint8 +.source 2 s2 guint8 .temp 2 t1 .temp 1 t2 .temp 1 t3 @@ -62,18 +62,18 @@ avgub d1, t2, t4 .function cogorc_downsample_vert_halfsite_2tap -.dest 1 d1 -.source 1 s1 -.source 1 s2 +.dest 1 d1 guint8 +.source 1 s1 guint8 +.source 1 s2 guint8 avgub d1, s1, s2 .function cogorc_downsample_vert_cosite_3tap -.dest 1 d1 -.source 1 s1 -.source 1 s2 -.source 1 s3 +.dest 1 d1 guint8 +.source 1 s1 guint8 +.source 1 s2 guint8 +.source 1 s3 guint8 .temp 2 t1 .temp 2 t2 .temp 2 t3 @@ -91,11 +91,11 @@ convsuswb d1, t1 .function cogorc_downsample_vert_halfsite_4tap -.dest 1 d1 -.source 1 s1 -.source 1 s2 -.source 1 s3 -.source 1 s4 +.dest 1 d1 guint8 +.source 1 s1 guint8 +.source 1 s2 guint8 +.source 1 s3 guint8 +.source 1 s4 guint8 .temp 2 t1 .temp 2 t2 .temp 2 t3 @@ -116,8 +116,8 @@ convsuswb d1, t2 .function cogorc_upsample_horiz_cosite_1tap -.dest 2 d1 guint8 -.source 1 s1 +.dest 2 d1 guint8 guint8 +.source 1 s1 guint8 .temp 1 t1 copyb t1, s1 @@ -125,9 +125,9 @@ mergebw d1, t1, t1 .function cogorc_upsample_horiz_cosite -.dest 2 d1 guint8 -.source 1 s1 -.source 1 s2 +.dest 2 d1 guint8 guint8 +.source 1 s1 guint8 +.source 1 s2 guint8 .temp 1 t1 .temp 1 t2 @@ -137,9 +137,9 @@ mergebw d1, t1, t2 .function cogorc_upsample_vert_avgub -.dest 1 d1 -.source 1 s1 -.source 1 s2 +.dest 1 d1 guint8 +.source 1 s1 guint8 +.source 1 s2 guint8 avgub d1, s1, s2 @@ -147,15 +147,15 @@ avgub d1, s1, s2 .function orc_unpack_yuyv_y -.dest 1 d1 -.source 2 s1 +.dest 1 d1 guint8 +.source 2 s1 guint8 select0wb d1, s1 .function orc_unpack_yuyv_u -.dest 1 d1 -.source 4 s1 +.dest 1 d1 guint8 +.source 4 s1 guint8 .temp 2 t1 select0lw t1, s1 @@ -163,8 +163,8 @@ select1wb d1, t1 .function orc_unpack_yuyv_v -.dest 1 d1 -.source 4 s1 +.dest 1 d1 guint8 +.source 4 s1 guint8 .temp 2 t1 select1lw t1, s1 @@ -172,10 +172,10 @@ select1wb d1, t1 .function orc_pack_yuyv -.dest 4 d1 -.source 2 s1 guint8 -.source 1 s2 -.source 1 s3 +.dest 4 d1 guint8 +.source 2 s1 guint8 guint8 +.source 1 s2 guint8 +.source 1 s3 guint8 .temp 1 t1 .temp 1 t2 .temp 2 t3 @@ -191,15 +191,15 @@ mergewl d1, t3, t4 .function orc_unpack_uyvy_y -.dest 1 d1 -.source 2 s1 +.dest 1 d1 guint8 +.source 2 s1 guint8 select1wb d1, s1 .function orc_unpack_uyvy_u -.dest 1 d1 -.source 4 s1 +.dest 1 d1 guint8 +.source 4 s1 guint8 .temp 2 t1 select0lw t1, s1 @@ -207,8 +207,8 @@ select0wb d1, t1 .function orc_unpack_uyvy_v -.dest 1 d1 -.source 4 s1 +.dest 1 d1 guint8 +.source 4 s1 guint8 .temp 2 t1 select1lw t1, s1 @@ -216,10 +216,10 @@ select0wb d1, t1 .function orc_pack_uyvy -.dest 4 d1 -.source 2 s1 guint8 -.source 1 s2 -.source 1 s3 +.dest 4 d1 guint8 +.source 2 s1 guint8 guint8 +.source 1 s2 guint8 +.source 1 s3 guint8 .temp 1 t1 .temp 1 t2 .temp 2 t3 @@ -235,9 +235,9 @@ mergewl d1, t3, t4 .function orc_matrix2_u8 -.dest 1 d1 guint8 -.source 1 s1 guint8 -.source 1 s2 guint8 +.dest 1 d1 guint8 guint8 +.source 1 s1 guint8 guint8 +.source 1 s2 guint8 guint8 .param 2 p1 .param 2 p2 .param 2 p3 @@ -255,9 +255,9 @@ convsuswb d1, t1 .function orc_matrix2_11_u8 -.dest 1 d1 guint8 -.source 1 s1 guint8 -.source 1 s2 guint8 +.dest 1 d1 guint8 guint8 +.source 1 s1 guint8 guint8 +.source 1 s2 guint8 guint8 .param 2 p1 .param 2 p2 .temp 2 t1 @@ -280,9 +280,9 @@ convsuswb d1, t3 .function orc_matrix2_12_u8 -.dest 1 d1 guint8 -.source 1 s1 guint8 -.source 1 s2 guint8 +.dest 1 d1 guint8 guint8 +.source 1 s1 guint8 guint8 +.source 1 s2 guint8 guint8 .param 2 p1 .param 2 p2 .temp 2 t1 @@ -306,10 +306,10 @@ convsuswb d1, t3 .function orc_matrix3_u8 -.dest 1 d1 guint8 -.source 1 s1 guint8 -.source 1 s2 guint8 -.source 1 s3 guint8 +.dest 1 d1 guint8 guint8 +.source 1 s1 guint8 guint8 +.source 1 s2 guint8 guint8 +.source 1 s3 guint8 guint8 .param 2 p1 .param 2 p2 .param 2 p3 @@ -331,10 +331,10 @@ convsuswb d1, t1 .function orc_matrix3_100_u8 -.dest 1 d1 guint8 -.source 1 s1 guint8 -.source 1 s2 guint8 -.source 1 s3 guint8 +.dest 1 d1 guint8 guint8 +.source 1 s1 guint8 guint8 +.source 1 s2 guint8 guint8 +.source 1 s3 guint8 guint8 .param 2 p1 .param 2 p2 .param 2 p3 @@ -361,10 +361,10 @@ convsuswb d1, t3 .function orc_matrix3_100_offset_u8 -.dest 1 d1 guint8 -.source 1 s1 guint8 -.source 1 s2 guint8 -.source 1 s3 guint8 +.dest 1 d1 guint8 guint8 +.source 1 s1 guint8 guint8 +.source 1 s2 guint8 guint8 +.source 1 s3 guint8 guint8 .param 2 p1 .param 2 p2 .param 2 p3 @@ -394,10 +394,10 @@ convsuswb d1, t1 .function orc_matrix3_000_u8 -.dest 1 d1 guint8 -.source 1 s1 guint8 -.source 1 s2 guint8 -.source 1 s3 guint8 +.dest 1 d1 guint8 guint8 +.source 1 s1 guint8 guint8 +.source 1 s2 guint8 guint8 +.source 1 s3 guint8 guint8 .param 2 p1 .param 2 p2 .param 2 p3 @@ -425,10 +425,10 @@ convwb d1, t1 .function orc_pack_123x -.dest 4 d1 guint32 -.source 1 s1 -.source 1 s2 -.source 1 s3 +.dest 4 d1 guint32 guint8 +.source 1 s1 guint8 +.source 1 s2 guint8 +.source 1 s3 guint8 .param 1 p1 .temp 2 t1 .temp 2 t2 @@ -439,10 +439,10 @@ mergewl d1, t1, t2 .function orc_pack_x123 -.dest 4 d1 guint32 -.source 1 s1 -.source 1 s2 -.source 1 s3 +.dest 4 d1 guint32 guint8 +.source 1 s1 guint8 +.source 1 s2 guint8 +.source 1 s3 guint8 .param 1 p1 .temp 2 t1 .temp 2 t2 @@ -453,9 +453,9 @@ mergewl d1, t1, t2 .function cogorc_combine2_u8 -.dest 1 d1 -.source 1 s1 -.source 1 s2 +.dest 1 d1 guint8 +.source 1 s1 guint8 +.source 1 s2 guint8 .param 2 p1 .param 2 p2 .temp 2 t1 @@ -471,12 +471,12 @@ convsuswb d1, t1 .function cogorc_convert_I420_UYVY -.dest 4 d1 -.dest 4 d2 -.source 2 y1 -.source 2 y2 -.source 1 u -.source 1 v +.dest 4 d1 guint8 +.dest 4 d2 guint8 +.source 2 y1 guint8 +.source 2 y2 guint8 +.source 1 u guint8 +.source 1 v guint8 .temp 2 uv mergebw uv, u, v @@ -485,12 +485,12 @@ x2 mergebw d2, uv, y2 .function cogorc_convert_I420_YUY2 -.dest 4 d1 -.dest 4 d2 -.source 2 y1 -.source 2 y2 -.source 1 u -.source 1 v +.dest 4 d1 guint8 +.dest 4 d2 guint8 +.source 2 y1 guint8 +.source 2 y2 guint8 +.source 1 u guint8 +.source 1 v guint8 .temp 2 uv mergebw uv, u, v @@ -500,12 +500,12 @@ x2 mergebw d2, y2, uv .function cogorc_convert_I420_AYUV -.dest 4 d1 -.dest 4 d2 -.source 1 y1 -.source 1 y2 -.source 1 u -.source 1 v +.dest 4 d1 guint8 +.dest 4 d2 guint8 +.source 1 y1 guint8 +.source 1 y2 guint8 +.source 1 u guint8 +.source 1 v guint8 .const 1 c255 255 .temp 2 uv .temp 2 ay @@ -522,12 +522,12 @@ mergewl d2, ay, uv .function cogorc_convert_YUY2_I420 -.dest 2 y1 -.dest 2 y2 -.dest 1 u -.dest 1 v -.source 4 yuv1 -.source 4 yuv2 +.dest 2 y1 guint8 +.dest 2 y2 guint8 +.dest 1 u guint8 +.dest 1 v guint8 +.source 4 yuv1 guint8 +.source 4 yuv2 guint8 .temp 2 t1 .temp 2 t2 .temp 2 ty @@ -542,17 +542,17 @@ splitwb v, u, t1 .function cogorc_convert_UYVY_YUY2 .flags 2d -.dest 4 yuy2 -.source 4 uyvy +.dest 4 yuy2 guint8 +.source 4 uyvy guint8 x2 swapw yuy2, uyvy .function cogorc_planar_chroma_420_422 .flags 2d -.dest 1 d1 -.dest 1 d2 -.source 1 s +.dest 1 d1 guint8 +.dest 1 d2 guint8 +.source 1 s guint8 copyb d1, s copyb d2, s @@ -560,9 +560,9 @@ copyb d2, s .function cogorc_planar_chroma_420_444 .flags 2d -.dest 2 d1 -.dest 2 d2 -.source 1 s +.dest 2 d1 guint8 +.dest 2 d2 guint8 +.source 1 s guint8 .temp 2 t splatbw t, s @@ -572,8 +572,8 @@ storew d2, t .function cogorc_planar_chroma_422_444 .flags 2d -.dest 2 d1 -.source 1 s +.dest 2 d1 guint8 +.source 1 s guint8 .temp 2 t splatbw t, s @@ -582,8 +582,8 @@ storew d1, t .function cogorc_planar_chroma_444_422 .flags 2d -.dest 1 d -.source 2 s +.dest 1 d guint8 +.source 2 s guint8 .temp 1 t1 .temp 1 t2 @@ -593,9 +593,9 @@ avgub d, t1, t2 .function cogorc_planar_chroma_444_420 .flags 2d -.dest 1 d -.source 2 s1 -.source 2 s2 +.dest 1 d guint8 +.source 2 s1 guint8 +.source 2 s2 guint8 .temp 2 t .temp 1 t1 .temp 1 t2 @@ -607,17 +607,17 @@ avgub d, t1, t2 .function cogorc_planar_chroma_422_420 .flags 2d -.dest 1 d -.source 1 s1 -.source 1 s2 +.dest 1 d guint8 +.source 1 s1 guint8 +.source 1 s2 guint8 avgub d, s1, s2 .function cogorc_convert_YUY2_AYUV .flags 2d -.dest 8 ayuv -.source 4 yuy2 +.dest 8 ayuv guint8 +.source 4 yuy2 guint8 .const 2 c255 0xff .temp 2 yy .temp 2 uv @@ -632,8 +632,8 @@ x2 mergewl ayuv, ayay, uvuv .function cogorc_convert_UYVY_AYUV .flags 2d -.dest 8 ayuv -.source 4 uyvy +.dest 8 ayuv guint8 +.source 4 uyvy guint8 .const 2 c255 0xff .temp 2 yy .temp 2 uv @@ -648,10 +648,10 @@ x2 mergewl ayuv, ayay, uvuv .function cogorc_convert_YUY2_Y42B .flags 2d -.dest 2 y -.dest 1 u -.dest 1 v -.source 4 yuy2 +.dest 2 y guint8 +.dest 1 u guint8 +.dest 1 v guint8 +.source 4 yuy2 guint8 .temp 2 uv x2 splitwb uv, y, yuy2 @@ -660,10 +660,10 @@ splitwb v, u, uv .function cogorc_convert_UYVY_Y42B .flags 2d -.dest 2 y -.dest 1 u -.dest 1 v -.source 4 uyvy +.dest 2 y guint8 +.dest 1 u guint8 +.dest 1 v guint8 +.source 4 uyvy guint8 .temp 2 uv x2 splitwb y, uv, uyvy @@ -672,10 +672,10 @@ splitwb v, u, uv .function cogorc_convert_YUY2_Y444 .flags 2d -.dest 2 y -.dest 2 uu -.dest 2 vv -.source 4 yuy2 +.dest 2 y guint8 +.dest 2 uu guint8 +.dest 2 vv guint8 +.source 4 yuy2 guint8 .temp 2 uv .temp 1 u .temp 1 v @@ -688,10 +688,10 @@ splatbw vv, v .function cogorc_convert_UYVY_Y444 .flags 2d -.dest 2 y -.dest 2 uu -.dest 2 vv -.source 4 uyvy +.dest 2 y guint8 +.dest 2 uu guint8 +.dest 2 vv guint8 +.source 4 uyvy guint8 .temp 2 uv .temp 1 u .temp 1 v @@ -703,12 +703,12 @@ splatbw vv, v .function cogorc_convert_UYVY_I420 -.dest 2 y1 -.dest 2 y2 -.dest 1 u -.dest 1 v -.source 4 yuv1 -.source 4 yuv2 +.dest 2 y1 guint8 +.dest 2 y2 guint8 +.dest 1 u guint8 +.dest 1 v guint8 +.source 4 yuv1 guint8 +.source 4 yuv2 guint8 .temp 2 t1 .temp 2 t2 .temp 2 ty @@ -724,12 +724,12 @@ splitwb v, u, t1 .function cogorc_convert_AYUV_I420 .flags 2d -.dest 2 y1 -.dest 2 y2 -.dest 1 u -.dest 1 v -.source 8 ayuv1 -.source 8 ayuv2 +.dest 2 y1 guint8 +.dest 2 y2 guint8 +.dest 1 u guint8 +.dest 1 v guint8 +.source 8 ayuv1 guint8 +.source 8 ayuv2 guint8 .temp 4 ay .temp 4 uv1 .temp 4 uv2 @@ -754,8 +754,8 @@ avgub v, t1, t2 .function cogorc_convert_AYUV_YUY2 .flags 2d -.dest 4 yuy2 -.source 8 ayuv +.dest 4 yuy2 guint8 +.source 8 ayuv guint8 .temp 2 yy .temp 2 uv1 .temp 2 uv2 @@ -771,8 +771,8 @@ x2 mergebw yuy2, yy, uv1 .function cogorc_convert_AYUV_UYVY .flags 2d -.dest 4 yuy2 -.source 8 ayuv +.dest 4 yuy2 guint8 +.source 8 ayuv guint8 .temp 2 yy .temp 2 uv1 .temp 2 uv2 @@ -789,10 +789,10 @@ x2 mergebw yuy2, uv1, yy .function cogorc_convert_AYUV_Y42B .flags 2d -.dest 2 y -.dest 1 u -.dest 1 v -.source 8 ayuv +.dest 2 y guint8 +.dest 1 u guint8 +.dest 1 v guint8 +.source 8 ayuv guint8 .temp 4 ayay .temp 4 uvuv .temp 2 uv1 @@ -807,10 +807,10 @@ x2 select1wb y, ayay .function cogorc_convert_AYUV_Y444 .flags 2d -.dest 1 y -.dest 1 u -.dest 1 v -.source 4 ayuv +.dest 1 y guint8 +.dest 1 u guint8 +.dest 1 v guint8 +.source 4 ayuv guint8 .temp 2 ay .temp 2 uv @@ -821,10 +821,10 @@ select1wb y, ay .function cogorc_convert_Y42B_YUY2 .flags 2d -.dest 4 yuy2 -.source 2 y -.source 1 u -.source 1 v +.dest 4 yuy2 guint8 +.source 2 y guint8 +.source 1 u guint8 +.source 1 v guint8 .temp 2 uv mergebw uv, u, v @@ -833,10 +833,10 @@ x2 mergebw yuy2, y, uv .function cogorc_convert_Y42B_UYVY .flags 2d -.dest 4 uyvy -.source 2 y -.source 1 u -.source 1 v +.dest 4 uyvy guint8 +.source 2 y guint8 +.source 1 u guint8 +.source 1 v guint8 .temp 2 uv mergebw uv, u, v @@ -845,10 +845,10 @@ x2 mergebw uyvy, uv, y .function cogorc_convert_Y42B_AYUV .flags 2d -.dest 8 ayuv -.source 2 yy -.source 1 u -.source 1 v +.dest 8 ayuv guint8 +.source 2 yy guint8 +.source 1 u guint8 +.source 1 v guint8 .const 1 c255 255 .temp 2 uv .temp 2 ay @@ -863,10 +863,10 @@ x2 mergewl ayuv, ayay, uvuv .function cogorc_convert_Y444_YUY2 .flags 2d -.dest 4 yuy2 -.source 2 y -.source 2 u -.source 2 v +.dest 4 yuy2 guint8 +.source 2 y guint8 +.source 2 u guint8 +.source 2 v guint8 .temp 2 uv .temp 4 uvuv .temp 2 uv1 @@ -880,10 +880,10 @@ x2 mergebw yuy2, y, uv .function cogorc_convert_Y444_UYVY .flags 2d -.dest 4 uyvy -.source 2 y -.source 2 u -.source 2 v +.dest 4 uyvy guint8 +.source 2 y guint8 +.source 2 u guint8 +.source 2 v guint8 .temp 2 uv .temp 4 uvuv .temp 2 uv1 @@ -897,10 +897,10 @@ x2 mergebw uyvy, uv, y .function cogorc_convert_Y444_AYUV .flags 2d -.dest 4 ayuv -.source 1 yy -.source 1 u -.source 1 v +.dest 4 ayuv guint8 +.source 1 yy guint8 +.source 1 u guint8 +.source 1 v guint8 .const 1 c255 255 .temp 2 uv .temp 2 ay @@ -913,8 +913,8 @@ mergewl ayuv, ay, uv .function cogorc_convert_AYUV_ARGB .flags 2d -.dest 4 argb -.source 4 ayuv +.dest 4 argb guint8 +.source 4 ayuv guint8 .temp 2 t1 .temp 2 t2 .temp 1 a @@ -978,8 +978,8 @@ x4 addb argb, x, 128 .function cogorc_convert_AYUV_BGRA .flags 2d -.dest 4 argb -.source 4 ayuv +.dest 4 argb guint8 +.source 4 ayuv guint8 .temp 2 t1 .temp 2 t2 .temp 1 a @@ -1044,8 +1044,8 @@ x4 addb argb, x, 128 .function cogorc_convert_AYUV_ABGR .flags 2d -.dest 4 argb -.source 4 ayuv +.dest 4 argb guint8 +.source 4 ayuv guint8 .temp 2 t1 .temp 2 t2 .temp 1 a @@ -1109,8 +1109,8 @@ x4 addb argb, x, 128 .function cogorc_convert_AYUV_RGBA .flags 2d -.dest 4 argb -.source 4 ayuv +.dest 4 argb guint8 +.source 4 ayuv guint8 .temp 2 t1 .temp 2 t2 .temp 1 a @@ -1173,10 +1173,10 @@ x4 addb argb, x, 128 .function cogorc_convert_I420_BGRA -.dest 4 argb -.source 1 y -.source 1 u -.source 1 v +.dest 4 argb guint8 +.source 1 y guint8 +.source 1 u guint8 +.source 1 v guint8 .temp 2 t1 .temp 2 t2 .temp 1 t3 @@ -1238,12 +1238,12 @@ x4 addb argb, x, c128 .function cogorc_convert_I420_BGRA_avg -.dest 4 argb -.source 1 y -.source 1 u1 -.source 1 u2 -.source 1 v1 -.source 1 v2 +.dest 4 argb guint8 +.source 1 y guint8 +.source 1 u1 guint8 +.source 1 u2 guint8 +.source 1 v1 guint8 +.source 1 v2 guint8 .temp 2 t1 .temp 2 t2 .temp 1 t3 @@ -1309,3 +1309,373 @@ x4 addb argb, x, c128 +.function cogorc_getline_I420 +.dest 4 d guint8 +.source 1 y guint8 +.source 1 u guint8 +.source 1 v guint8 +.const 1 c255 255 +.temp 2 uv +.temp 2 ay +.temp 1 tu +.temp 1 tv + +loadupdb tu, u +loadupdb tv, v +mergebw uv, tu, tv +mergebw ay, c255, y +mergewl d, ay, uv + + +.function cogorc_getline_YUY2 +.dest 8 ayuv guint8 +.source 4 yuy2 guint8 +.const 2 c255 0xff +.temp 2 yy +.temp 2 uv +.temp 4 ayay +.temp 4 uvuv + +x2 splitwb uv, yy, yuy2 +x2 mergebw ayay, c255, yy +mergewl uvuv, uv, uv +x2 mergewl ayuv, ayay, uvuv + + +.function cogorc_getline_UYVY +.dest 8 ayuv guint8 +.source 4 uyvy guint8 +.const 2 c255 0xff +.temp 2 yy +.temp 2 uv +.temp 4 ayay +.temp 4 uvuv + +x2 splitwb yy, uv, uyvy +x2 mergebw ayay, c255, yy +mergewl uvuv, uv, uv +x2 mergewl ayuv, ayay, uvuv + + +.function cogorc_getline_YVYU +.dest 8 ayuv guint8 +.source 4 uyvy guint8 +.const 2 c255 0xff +.temp 2 yy +.temp 2 uv +.temp 4 ayay +.temp 4 uvuv + +x2 splitwb yy, uv, uyvy +x2 mergebw ayay, c255, yy +mergewl uvuv, uv, uv +x2 mergewl ayuv, ayay, uvuv + + +.function cogorc_getline_Y42B +.dest 8 ayuv guint8 +.source 2 yy guint8 +.source 1 u guint8 +.source 1 v guint8 +.const 1 c255 255 +.temp 2 uv +.temp 2 ay +.temp 4 uvuv +.temp 4 ayay + +mergebw uv, u, v +x2 mergebw ayay, c255, yy +mergewl uvuv, uv, uv +x2 mergewl ayuv, ayay, uvuv + + +.function cogorc_getline_Y444 +.dest 4 ayuv guint8 +.source 1 y guint8 +.source 1 u guint8 +.source 1 v guint8 +.const 1 c255 255 +.temp 2 uv +.temp 2 ay + +mergebw uv, u, v +mergebw ay, c255, y +mergewl ayuv, ay, uv + + +.function cogorc_getline_Y800 +.dest 4 ayuv guint8 +.source 1 y guint8 +.const 1 c255 255 +.const 2 c0xffff 0xffff +.temp 2 ay + +mergebw ay, c255, y +mergewl ayuv, ay, c0xffff + + +.function cogorc_getline_BGRA +.dest 4 argb guint8 +.source 4 bgra guint8 + +swapl argb, bgra + + +.function cogorc_getline_ABGR +.dest 4 argb guint8 +.source 4 abgr guint8 +.temp 1 a +.temp 1 r +.temp 1 g +.temp 1 b +.temp 2 gr +.temp 2 ab +.temp 2 ar +.temp 2 gb + +splitlw gr, ab, abgr +splitwb r, g, gr +splitwb b, a, ab +mergebw ar, a, r +mergebw gb, g, b +mergewl argb, ar, gb + + +.function cogorc_getline_RGBA +.dest 4 argb guint8 +.source 4 rgba guint8 +.temp 1 a +.temp 1 r +.temp 1 g +.temp 1 b +.temp 2 rg +.temp 2 ba +.temp 2 ar +.temp 2 gb + +splitlw ba, rg, rgba +splitwb g, r, rg +splitwb a, b, ba +mergebw ar, a, r +mergebw gb, g, b +mergewl argb, ar, gb + + +.function cogorc_getline_NV12 +.dest 8 d guint8 +.source 2 y guint8 +.source 2 uv guint8 +.const 1 c255 255 +.temp 4 ay +.temp 4 uvuv + +mergewl uvuv, uv, uv +x2 mergebw ay, c255, y +x2 mergewl d, ay, uvuv + + +.function cogorc_getline_NV21 +.dest 8 d guint8 +.source 2 y guint8 +.source 2 vu guint8 +.const 1 c255 255 +.temp 2 uv +.temp 4 ay +.temp 4 uvuv + +swapw uv, vu +mergewl uvuv, uv, uv +x2 mergebw ay, c255, y +x2 mergewl d, ay, uvuv + + +.function cogorc_putline_I420 +.dest 2 y guint8 +.dest 1 u guint8 +.dest 1 v guint8 +.source 8 ayuv guint8 +.temp 4 ay +.temp 4 uv +.temp 2 uu +.temp 2 vv +.temp 1 t1 +.temp 1 t2 + +x2 splitlw uv, ay, ayuv +x2 select1wb y, ay +x2 splitwb vv, uu, uv +splitwb t1, t2, uu +avgub u, t1, t2 +splitwb t1, t2, vv +avgub v, t1, t2 + + + +.function cogorc_putline_YUY2 +.dest 4 yuy2 guint8 +.source 8 ayuv guint8 +.temp 2 yy +.temp 2 uv1 +.temp 2 uv2 +.temp 4 ayay +.temp 4 uvuv + +x2 splitlw uvuv, ayay, ayuv +splitlw uv1, uv2, uvuv +x2 avgub uv1, uv1, uv2 +x2 select1wb yy, ayay +x2 mergebw yuy2, yy, uv1 + + +.function cogorc_putline_YVYU +.dest 4 yuy2 guint8 +.source 8 ayuv guint8 +.temp 2 yy +.temp 2 uv1 +.temp 2 uv2 +.temp 4 ayay +.temp 4 uvuv + +x2 splitlw uvuv, ayay, ayuv +splitlw uv1, uv2, uvuv +x2 avgub uv1, uv1, uv2 +x2 select1wb yy, ayay +swapw uv1, uv1 +x2 mergebw yuy2, yy, uv1 + + +.function cogorc_putline_UYVY +.dest 4 yuy2 guint8 +.source 8 ayuv guint8 +.temp 2 yy +.temp 2 uv1 +.temp 2 uv2 +.temp 4 ayay +.temp 4 uvuv + +x2 splitlw uvuv, ayay, ayuv +splitlw uv1, uv2, uvuv +x2 avgub uv1, uv1, uv2 +x2 select1wb yy, ayay +x2 mergebw yuy2, uv1, yy + + + +.function cogorc_putline_Y42B +.dest 2 y guint8 +.dest 1 u guint8 +.dest 1 v guint8 +.source 8 ayuv guint8 +.temp 4 ayay +.temp 4 uvuv +.temp 2 uv1 +.temp 2 uv2 + +x2 splitlw uvuv, ayay, ayuv +splitlw uv1, uv2, uvuv +x2 avgub uv1, uv1, uv2 +splitwb v, u, uv1 +x2 select1wb y, ayay + + +.function cogorc_putline_Y444 +.dest 1 y guint8 +.dest 1 u guint8 +.dest 1 v guint8 +.source 4 ayuv guint8 +.temp 2 ay +.temp 2 uv + +splitlw uv, ay, ayuv +splitwb v, u, uv +select1wb y, ay + + +.function cogorc_putline_Y800 +.dest 1 y guint8 +.source 4 ayuv guint8 +.temp 2 ay + +select0lw ay, ayuv +select1wb y, ay + + +.function cogorc_putline_BGRA +.dest 4 bgra guint8 +.source 4 argb guint8 + +swapl bgra, argb + + +.function cogorc_putline_ABGR +.dest 4 abgr guint8 +.source 4 argb guint8 +.temp 1 a +.temp 1 r +.temp 1 g +.temp 1 b +.temp 2 gr +.temp 2 ab +.temp 2 ar +.temp 2 gb + +splitlw gb, ar, argb +splitwb b, g, gb +splitwb r, a, ar +mergebw ab, a, b +mergebw gr, g, r +mergewl abgr, ab, gr + + +.function cogorc_putline_RGBA +.dest 4 rgba guint8 +.source 4 argb guint8 +.temp 1 a +.temp 1 r +.temp 1 g +.temp 1 b +.temp 2 rg +.temp 2 ba +.temp 2 ar +.temp 2 gb + +splitlw gb, ar, argb +splitwb b, g, gb +splitwb r, a, ar +mergebw ba, b, a +mergebw rg, r, g +mergewl rgba, rg, ba + + +.function cogorc_putline_NV12 +.dest 2 y guint8 +.dest 2 uv guint8 +.source 8 ayuv guint8 +.temp 4 ay +.temp 4 uvuv +.temp 2 uv1 +.temp 2 uv2 + +x2 splitlw uvuv, ay, ayuv +x2 select1wb y, ay +splitlw uv1, uv2, uvuv +x2 avgub uv, uv1, uv2 + + +.function cogorc_putline_NV21 +.dest 2 y guint8 +.dest 2 vu guint8 +.source 8 ayuv guint8 +.temp 4 ay +.temp 4 uvuv +.temp 2 uv1 +.temp 2 uv2 +.temp 2 uv + +x2 splitlw uvuv, ay, ayuv +x2 select1wb y, ay +splitlw uv1, uv2, uvuv +x2 avgub uv, uv1, uv2 +swapw vu, uv + +