[MOVED FROM BAD 32/68] colorspace: Add conversion code
authorDavid Schleef <ds@schleef.org>
Tue, 14 Sep 2010 01:49:43 +0000 (18:49 -0700)
committerWim Taymans <wim.taymans@collabora.co.uk>
Wed, 15 Jun 2011 14:12:54 +0000 (16:12 +0200)
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.

gst/colorspace/Makefile.am
gst/colorspace/colorspace.c [new file with mode: 0644]
gst/colorspace/colorspace.h [new file with mode: 0644]
gst/colorspace/gstcolorspace.c
gst/colorspace/gstcolorspace.h
gst/colorspace/gstcolorspaceorc.orc

index e011bb9..a297f31 100644 (file)
@@ -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 (file)
index 0000000..af6c7f2
--- /dev/null
@@ -0,0 +1,1240 @@
+/* GStreamer
+ * Copyright (C) 2010 David Schleef <ds@schleef.org>
+ *
+ * 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 <glib.h>
+#include <string.h>
+#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 (file)
index 0000000..6add546
--- /dev/null
@@ -0,0 +1,69 @@
+/* Colorspace conversion functions
+ * Copyright (C) 2010 David Schleef <ds@schleef.org>
+ *
+ * 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 <gst/video/video.h>
+
+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__ */
index 6d1262b..0b70408 100644 (file)
@@ -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);
index c4bce92..809704f 100644 (file)
@@ -25,6 +25,7 @@
 #include <gst/gst.h>
 #include <gst/video/video.h>
 #include <gst/video/gstvideofilter.h>
+#include "colorspace.h"
 
 G_BEGIN_DECLS
 
@@ -52,6 +53,8 @@ struct _GstCsp {
   GstVideoFormat from_format;
   GstVideoFormat to_format;
   guint32 *palette;
+
+  ColorspaceConvert *convert;
 };
 
 struct _GstCspClass
index 6d8fdfd..df6773b 100644 (file)
@@ -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
+
+