[MOVED FROM BAD 58/68] colorspace: Add 16-bit-per-channel handling
authorDavid Schleef <ds@schleef.org>
Sat, 19 Feb 2011 21:12:41 +0000 (13:12 -0800)
committerWim Taymans <wim.taymans@collabora.co.uk>
Wed, 15 Jun 2011 14:12:56 +0000 (16:12 +0200)
gst/colorspace/colorspace.c
gst/colorspace/colorspace.h
gst/colorspace/gstcolorspace.c

index e69ab80..b949fe2 100644 (file)
@@ -27,8 +27,6 @@
 #include <string.h>
 #include "gstcolorspaceorc.h"
 
-/* For GST_CHECK_PLUGINS_BASE_VERSION() */
-#include <gst/pbutils/pbutils.h>
 
 static void colorspace_convert_generic (ColorspaceConvert * convert,
     guint8 * dest, const guint8 * src);
@@ -75,6 +73,13 @@ colorspace_convert_new (GstVideoFormat to_format, ColorSpaceColorSpec to_spec,
   convert->width = width;
   convert->convert = colorspace_convert_generic;
 
+  if (gst_video_format_get_component_depth (to_format, 0) > 8 ||
+      gst_video_format_get_component_depth (from_format, 0) > 8) {
+    convert->use_16bit = TRUE;
+  } else {
+    convert->use_16bit = FALSE;
+  }
+
   for (i = 0; i < 4; i++) {
     convert->dest_stride[i] = gst_video_format_get_row_stride (to_format, i,
         width);
@@ -98,9 +103,9 @@ colorspace_convert_new (GstVideoFormat to_format, ColorSpaceColorSpec to_spec,
   colorspace_convert_lookup_fastpath (convert);
   colorspace_convert_lookup_getput (convert);
 
-  convert->tmpline = g_malloc (sizeof (guint32) * width * 2);
+  convert->tmpline = g_malloc (sizeof (guint8) * (width + 8) * 4);
+  convert->tmpline16 = g_malloc (sizeof (guint16) * (width + 8) * 4);
 
-#if GST_CHECK_PLUGINS_BASE_VERSION(0, 10, 32)
   if (to_format == GST_VIDEO_FORMAT_RGB8_PALETTED) {
     /* build poor man's palette, taken from ffmpegcolorspace */
     static const guint8 pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
@@ -122,7 +127,6 @@ colorspace_convert_new (GstVideoFormat to_format, ColorSpaceColorSpec to_spec,
     while (i < 256)
       palette[i++] = 0xff000000;
   }
-#endif
 
   return convert;
 }
@@ -130,10 +134,9 @@ colorspace_convert_new (GstVideoFormat to_format, ColorSpaceColorSpec to_spec,
 void
 colorspace_convert_free (ColorspaceConvert * convert)
 {
-  if (convert->palette)
-    g_free (convert->palette);
-  if (convert->tmpline)
-    g_free (convert->tmpline);
+  g_free (convert->palette);
+  g_free (convert->tmpline);
+  g_free (convert->tmpline16);
 
   g_free (convert);
 }
@@ -390,25 +393,131 @@ putline_v210 (ColorspaceConvert * convert, guint8 * dest, const guint8 * src,
     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];
+    y0 = src[4 * (i + 0) + 1] << 2;
+    y1 = src[4 * (i + 1) + 1] << 2;
+    y2 = src[4 * (i + 2) + 1] << 2;
+    y3 = src[4 * (i + 3) + 1] << 2;
+    y4 = src[4 * (i + 4) + 1] << 2;
+    y5 = src[4 * (i + 5) + 1] << 2;
 
-    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;
+    u0 = (src[4 * (i + 0) + 2] + src[4 * (i + 1) + 2]) << 1;
+    u1 = (src[4 * (i + 2) + 2] + src[4 * (i + 3) + 2]) << 1;
+    u2 = (src[4 * (i + 4) + 2] + src[4 * (i + 5) + 2]) << 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;
+    v0 = (src[4 * (i + 0) + 3] + src[4 * (i + 1) + 3]) << 1;
+    v1 = (src[4 * (i + 2) + 3] + src[4 * (i + 3) + 3]) << 1;
+    v2 = (src[4 * (i + 4) + 3] + src[4 * (i + 5) + 3]) << 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);
+    a0 = u0 | (y0 << 10) | (v0 << 20);
+    a1 = y1 | (u1 << 10) | (y2 << 20);
+    a2 = v1 | (y3 << 10) | (u2 << 20);
+    a3 = y4 | (v2 << 10) | (y5 << 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
+getline16_v210 (ColorspaceConvert * convert, guint16 * dest, const guint8 * src,
+    int j)
+{
+  int i;
+  const 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) << 6;
+    y0 = ((a0 >> 10) & 0x3ff) << 6;
+    v0 = ((a0 >> 20) & 0x3ff) << 6;
+    y1 = ((a1 >> 0) & 0x3ff) << 6;
+
+    u2 = ((a1 >> 10) & 0x3ff) << 6;
+    y2 = ((a1 >> 20) & 0x3ff) << 6;
+    v2 = ((a2 >> 0) & 0x3ff) << 6;
+    y3 = ((a2 >> 10) & 0x3ff) << 6;
+
+    u4 = ((a2 >> 20) & 0x3ff) << 6;
+    y4 = ((a3 >> 0) & 0x3ff) << 6;
+    v4 = ((a3 >> 10) & 0x3ff) << 6;
+    y5 = ((a3 >> 20) & 0x3ff) << 6;
+
+    dest[4 * (i + 0) + 0] = 0xffff;
+    dest[4 * (i + 0) + 1] = y0;
+    dest[4 * (i + 0) + 2] = u0;
+    dest[4 * (i + 0) + 3] = v0;
+
+    dest[4 * (i + 1) + 0] = 0xffff;
+    dest[4 * (i + 1) + 1] = y1;
+    dest[4 * (i + 1) + 2] = u0;
+    dest[4 * (i + 1) + 3] = v0;
+
+    dest[4 * (i + 2) + 0] = 0xffff;
+    dest[4 * (i + 2) + 1] = y2;
+    dest[4 * (i + 2) + 2] = u2;
+    dest[4 * (i + 2) + 3] = v2;
+
+    dest[4 * (i + 3) + 0] = 0xffff;
+    dest[4 * (i + 3) + 1] = y3;
+    dest[4 * (i + 3) + 2] = u2;
+    dest[4 * (i + 3) + 3] = v2;
+
+    dest[4 * (i + 4) + 0] = 0xffff;
+    dest[4 * (i + 4) + 1] = y4;
+    dest[4 * (i + 4) + 2] = u4;
+    dest[4 * (i + 4) + 3] = v4;
+
+    dest[4 * (i + 5) + 0] = 0xffff;
+    dest[4 * (i + 5) + 1] = y5;
+    dest[4 * (i + 5) + 2] = u4;
+    dest[4 * (i + 5) + 3] = v4;
+
+  }
+}
+
+static void
+putline16_v210 (ColorspaceConvert * convert, guint8 * dest, const guint16 * 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] >> 6;
+    y1 = src[4 * (i + 1) + 1] >> 6;
+    y2 = src[4 * (i + 2) + 1] >> 6;
+    y3 = src[4 * (i + 3) + 1] >> 6;
+    y4 = src[4 * (i + 4) + 1] >> 6;
+    y5 = src[4 * (i + 5) + 1] >> 6;
+
+    u0 = (src[4 * (i + 0) + 2] + src[4 * (i + 1) + 2] + 1) >> 7;
+    u1 = (src[4 * (i + 2) + 2] + src[4 * (i + 3) + 2] + 1) >> 7;
+    u2 = (src[4 * (i + 4) + 2] + src[4 * (i + 5) + 2] + 1) >> 7;
+
+    v0 = (src[4 * (i + 0) + 3] + src[4 * (i + 1) + 3] + 1) >> 7;
+    v1 = (src[4 * (i + 2) + 3] + src[4 * (i + 3) + 3] + 1) >> 7;
+    v2 = (src[4 * (i + 4) + 3] + src[4 * (i + 5) + 3] + 1) >> 7;
+
+    a0 = u0 | (y0 << 10) | (v0 << 20);
+    a1 = y1 | (u1 << 10) | (y2 << 20);
+    a2 = v1 | (y3 << 10) | (u2 << 20);
+    a3 = y4 | (v2 << 10) | (y5 << 20);
 
     GST_WRITE_UINT32_LE (destline + (i / 6) * 16 + 0, a0);
     GST_WRITE_UINT32_LE (destline + (i / 6) * 16 + 4, a1);
@@ -425,9 +534,9 @@ getline_v216 (ColorspaceConvert * convert, guint8 * dest, const guint8 * src,
   const 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);
+    dest[i * 4 + 1] = GST_READ_UINT16_LE (srcline + i * 4 + 2) >> 8;
+    dest[i * 4 + 2] = GST_READ_UINT16_LE (srcline + (i >> 1) * 8 + 0) >> 8;
+    dest[i * 4 + 3] = GST_READ_UINT16_LE (srcline + (i >> 1) * 8 + 4) >> 8;
   }
 }
 
@@ -446,6 +555,34 @@ putline_v216 (ColorspaceConvert * convert, guint8 * dest, const guint8 * src,
 }
 
 static void
+getline16_v216 (ColorspaceConvert * convert, guint16 * dest, const guint8 * src,
+    int j)
+{
+  int i;
+  const guint8 *srcline = FRAME_GET_LINE (src, 0, j);
+  for (i = 0; i < convert->width; i++) {
+    dest[i * 4 + 0] = 0xffff;
+    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
+putline16_v216 (ColorspaceConvert * convert, guint8 * dest, const guint16 * 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]);
+    GST_WRITE_UINT16_LE (destline + i * 8 + 2, src[(i * 2 + 0) * 4 + 1]);
+    GST_WRITE_UINT16_LE (destline + i * 8 + 4, src[(i * 2 + 1) * 4 + 3]);
+    GST_WRITE_UINT16_LE (destline + i * 8 + 8, src[(i * 2 + 0) * 4 + 1]);
+  }
+}
+
+static void
 getline_Y41B (ColorspaceConvert * convert, guint8 * dest, const guint8 * src,
     int j)
 {
@@ -875,7 +1012,6 @@ putline_A420 (ColorspaceConvert * convert, guint8 * dest, const guint8 * src,
       FRAME_GET_LINE (dest, 3, j), src, convert->width / 2);
 }
 
-#if GST_CHECK_PLUGINS_BASE_VERSION(0, 10, 32)
 static void
 getline_RGB8P (ColorspaceConvert * convert, guint8 * dest, const guint8 * src,
     int j)
@@ -1053,7 +1189,64 @@ putline_IYU1 (ColorspaceConvert * convert, guint8 * dest, const guint8 * src,
     destline[(i >> 2) * 6 + 3] = src[i * 4 + 3];
   }
 }
-#endif
+
+static void
+getline_AY64 (ColorspaceConvert * convert, guint8 * dest, const guint8 * src,
+    int j)
+{
+  int i;
+  const guint16 *srcline = (const guint16 *) FRAME_GET_LINE (src, 0, j);
+  for (i = 0; i < convert->width * 4; i++) {
+    dest[i] = srcline[i] >> 8;
+  }
+}
+
+static void
+putline_AY64 (ColorspaceConvert * convert, guint8 * dest, const guint8 * src,
+    int j)
+{
+  int i;
+  guint16 *destline = (guint16 *) FRAME_GET_LINE (dest, 0, j);
+  for (i = 0; i < convert->width * 4; i++) {
+    destline[i] = src[i] << 8;
+  }
+}
+
+static void
+getline16_AY64 (ColorspaceConvert * convert, guint16 * dest, const guint8 * src,
+    int j)
+{
+  memcpy (dest, FRAME_GET_LINE (src, 0, j), convert->width * 8);
+}
+
+static void
+putline16_AY64 (ColorspaceConvert * convert, guint8 * dest, const guint16 * src,
+    int j)
+{
+  memcpy (FRAME_GET_LINE (dest, 0, j), src, convert->width * 8);
+}
+
+static void
+getline16_convert (ColorspaceConvert * convert, guint16 * dest,
+    const guint8 * src, int j)
+{
+  int i;
+  convert->getline (convert, convert->tmpline, src, j);
+  for (i = 0; i < convert->width * 4; i++) {
+    dest[i] = convert->tmpline[i] << 8;
+  }
+}
+
+static void
+putline16_convert (ColorspaceConvert * convert, guint8 * dest,
+    const guint16 * src, int j)
+{
+  int i;
+  for (i = 0; i < convert->width * 4; i++) {
+    convert->tmpline[i] = src[i] >> 8;
+  }
+  convert->putline (convert, dest, convert->tmpline, j);
+}
 
 typedef struct
 {
@@ -1062,6 +1255,10 @@ typedef struct
       const guint8 * src, int j);
   void (*putline) (ColorspaceConvert * convert, guint8 * dest,
       const guint8 * src, int j);
+  void (*getline16) (ColorspaceConvert * convert, guint16 * dest,
+      const guint8 * src, int j);
+  void (*putline16) (ColorspaceConvert * convert, guint8 * dest,
+      const guint16 * src, int j);
 } ColorspaceLine;
 static const ColorspaceLine lines[] = {
   {GST_VIDEO_FORMAT_I420, getline_I420, putline_I420},
@@ -1083,8 +1280,10 @@ static const ColorspaceLine lines[] = {
   {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_v210, getline_v210, putline_v210,
+      getline16_v210, putline16_v210},
+  {GST_VIDEO_FORMAT_v216, getline_v216, putline_v216,
+      getline16_v216, putline16_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},
@@ -1099,12 +1298,14 @@ static const ColorspaceLine lines[] = {
   {GST_VIDEO_FORMAT_BGR15, getline_BGR15, putline_BGR15},
   {GST_VIDEO_FORMAT_UYVP, getline_UYVP, putline_UYVP},
   {GST_VIDEO_FORMAT_A420, getline_A420, putline_A420}
-#if GST_CHECK_PLUGINS_BASE_VERSION(0, 10, 32)
   , {GST_VIDEO_FORMAT_RGB8_PALETTED, getline_RGB8P, putline_RGB8P},
   {GST_VIDEO_FORMAT_YUV9, getline_YUV9, putline_YUV9},
   {GST_VIDEO_FORMAT_YVU9, getline_YUV9, putline_YUV9},  /* alias */
-  {GST_VIDEO_FORMAT_IYU1, getline_IYU1, putline_IYU1}
-#endif
+  {GST_VIDEO_FORMAT_IYU1, getline_IYU1, putline_IYU1},
+  {GST_VIDEO_FORMAT_ARGB64, getline_AY64, putline_AY64, getline16_AY64,
+      putline16_AY64},
+  {GST_VIDEO_FORMAT_AYUV64, getline_AY64, putline_AY64, getline16_AY64,
+      putline16_AY64}
 };
 
 static void
@@ -1251,6 +1452,151 @@ matrix_identity (ColorspaceConvert * convert)
   /* do nothing */
 }
 
+static void
+matrix16_rgb_to_yuv_bt470_6 (ColorspaceConvert * convert)
+{
+  int i;
+  int r, g, b;
+  int y, u, v;
+  guint16 *tmpline = convert->tmpline16;
+
+  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 * 256) >> 8;
+    u = (-38 * r - 74 * g + 112 * b + 32768 * 256) >> 8;
+    v = (112 * r - 94 * g - 18 * b + 32768 * 256) >> 8;
+
+    tmpline[i * 4 + 1] = CLAMP (y, 0, 65535);
+    tmpline[i * 4 + 2] = CLAMP (u, 0, 65535);
+    tmpline[i * 4 + 3] = CLAMP (v, 0, 65535);
+  }
+}
+
+static void
+matrix16_rgb_to_yuv_bt709 (ColorspaceConvert * convert)
+{
+  int i;
+  int r, g, b;
+  int y, u, v;
+  guint16 *tmpline = convert->tmpline16;
+
+  for (i = 0; i < convert->width; i++) {
+    r = tmpline[i * 4 + 1];
+    g = tmpline[i * 4 + 2];
+    b = tmpline[i * 4 + 3];
+
+    y = (47 * r + 157 * g + 16 * b + 4096 * 256) >> 8;
+    u = (-26 * r - 87 * g + 112 * b + 32768 * 256) >> 8;
+    v = (112 * r - 102 * g - 10 * b + 32768 * 256) >> 8;
+
+    tmpline[i * 4 + 1] = CLAMP (y, 0, 65535);
+    tmpline[i * 4 + 2] = CLAMP (u, 0, 65535);
+    tmpline[i * 4 + 3] = CLAMP (v, 0, 65535);
+  }
+}
+
+static void
+matrix16_yuv_bt470_6_to_rgb (ColorspaceConvert * convert)
+{
+  int i;
+  int r, g, b;
+  int y, u, v;
+  guint16 *tmpline = convert->tmpline16;
+
+  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 * 256) >> 8;
+    g = (298 * y - 100 * u - 208 * v + 34707 * 256) >> 8;
+    b = (298 * y + 516 * u - 70870 * 256) >> 8;
+
+    tmpline[i * 4 + 1] = CLAMP (y, 0, 65535);
+    tmpline[i * 4 + 2] = CLAMP (u, 0, 65535);
+    tmpline[i * 4 + 3] = CLAMP (v, 0, 65535);
+  }
+}
+
+static void
+matrix16_yuv_bt709_to_rgb (ColorspaceConvert * convert)
+{
+  int i;
+  int r, g, b;
+  int y, u, v;
+  guint16 *tmpline = convert->tmpline16;
+
+  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 + 459 * v - 63514 * 256) >> 8;
+    g = (298 * y - 55 * u - 136 * v + 19681 * 256) >> 8;
+    b = (298 * y + 541 * u - 73988 * 256) >> 8;
+
+    tmpline[i * 4 + 1] = CLAMP (y, 0, 65535);
+    tmpline[i * 4 + 2] = CLAMP (u, 0, 65535);
+    tmpline[i * 4 + 3] = CLAMP (v, 0, 65535);
+  }
+}
+
+static void
+matrix16_yuv_bt709_to_yuv_bt470_6 (ColorspaceConvert * convert)
+{
+  int i;
+  int r, g, b;
+  int y, u, v;
+  guint16 *tmpline = convert->tmpline16;
+
+  for (i = 0; i < convert->width; i++) {
+    y = tmpline[i * 4 + 1];
+    u = tmpline[i * 4 + 2];
+    v = tmpline[i * 4 + 3];
+
+    r = (256 * y + 25 * u + 49 * v - 9536 * 256) >> 8;
+    g = (253 * u - 28 * v + 3958 * 256) >> 8;
+    b = (-19 * u + 252 * v + 2918 * 256) >> 8;
+
+    tmpline[i * 4 + 1] = CLAMP (y, 0, 65535);
+    tmpline[i * 4 + 2] = CLAMP (u, 0, 65535);
+    tmpline[i * 4 + 3] = CLAMP (v, 0, 65535);
+  }
+}
+
+static void
+matrix16_yuv_bt470_6_to_yuv_bt709 (ColorspaceConvert * convert)
+{
+  int i;
+  int r, g, b;
+  int y, u, v;
+  guint16 *tmpline = convert->tmpline16;
+
+  for (i = 0; i < convert->width; i++) {
+    y = tmpline[i * 4 + 1];
+    u = tmpline[i * 4 + 2];
+    v = tmpline[i * 4 + 3];
+
+    r = (256 * y - 30 * u - 53 * v + 10600 * 256) >> 8;
+    g = (261 * u + 29 * v - 4367 * 256) >> 8;
+    b = (19 * u + 262 * v - 3289 * 256) >> 8;
+
+    tmpline[i * 4 + 1] = CLAMP (y, 0, 65535);
+    tmpline[i * 4 + 2] = CLAMP (u, 0, 65535);
+    tmpline[i * 4 + 3] = CLAMP (v, 0, 65535);
+  }
+}
+
+static void
+matrix16_identity (ColorspaceConvert * convert)
+{
+  /* do nothing */
+}
+
+
 
 static void
 colorspace_convert_lookup_getput (ColorspaceConvert * convert)
@@ -1258,41 +1604,60 @@ colorspace_convert_lookup_getput (ColorspaceConvert * convert)
   int i;
 
   convert->getline = NULL;
+  convert->getline16 = NULL;
   for (i = 0; i < sizeof (lines) / sizeof (lines[0]); i++) {
     if (lines[i].format == convert->from_format) {
       convert->getline = lines[i].getline;
+      convert->getline16 = lines[i].getline16;
       break;
     }
   }
   convert->putline = NULL;
+  convert->putline16 = NULL;
   for (i = 0; i < sizeof (lines) / sizeof (lines[0]); i++) {
     if (lines[i].format == convert->to_format) {
       convert->putline = lines[i].putline;
+      convert->putline16 = lines[i].putline16;
       break;
     }
   }
   GST_DEBUG ("get %p put %p", convert->getline, convert->putline);
 
-  if (convert->from_spec == convert->to_spec)
+  if (convert->getline16 == NULL) {
+    convert->getline16 = getline16_convert;
+  }
+  if (convert->putline16 == NULL) {
+    convert->putline16 = putline16_convert;
+  }
+
+  if (convert->from_spec == convert->to_spec) {
     convert->matrix = matrix_identity;
-  else if (convert->from_spec == COLOR_SPEC_RGB
-      && convert->to_spec == COLOR_SPEC_YUV_BT470_6)
+    convert->matrix16 = matrix16_identity;
+  } else if (convert->from_spec == COLOR_SPEC_RGB
+      && convert->to_spec == COLOR_SPEC_YUV_BT470_6) {
     convert->matrix = matrix_rgb_to_yuv_bt470_6;
-  else if (convert->from_spec == COLOR_SPEC_RGB
-      && convert->to_spec == COLOR_SPEC_YUV_BT709)
+    convert->matrix16 = matrix16_rgb_to_yuv_bt470_6;
+  } else if (convert->from_spec == COLOR_SPEC_RGB
+      && convert->to_spec == COLOR_SPEC_YUV_BT709) {
     convert->matrix = matrix_rgb_to_yuv_bt709;
-  else if (convert->from_spec == COLOR_SPEC_YUV_BT470_6
-      && convert->to_spec == COLOR_SPEC_RGB)
+    convert->matrix16 = matrix16_rgb_to_yuv_bt709;
+  } else if (convert->from_spec == COLOR_SPEC_YUV_BT470_6
+      && convert->to_spec == COLOR_SPEC_RGB) {
     convert->matrix = matrix_yuv_bt470_6_to_rgb;
-  else if (convert->from_spec == COLOR_SPEC_YUV_BT709
-      && convert->to_spec == COLOR_SPEC_RGB)
+    convert->matrix16 = matrix16_yuv_bt470_6_to_rgb;
+  } else if (convert->from_spec == COLOR_SPEC_YUV_BT709
+      && convert->to_spec == COLOR_SPEC_RGB) {
     convert->matrix = matrix_yuv_bt709_to_rgb;
-  else if (convert->from_spec == COLOR_SPEC_YUV_BT709
-      && convert->to_spec == COLOR_SPEC_YUV_BT470_6)
+    convert->matrix16 = matrix16_yuv_bt709_to_rgb;
+  } else if (convert->from_spec == COLOR_SPEC_YUV_BT709
+      && convert->to_spec == COLOR_SPEC_YUV_BT470_6) {
     convert->matrix = matrix_yuv_bt709_to_yuv_bt470_6;
-  else if (convert->from_spec == COLOR_SPEC_YUV_BT470_6
-      && convert->to_spec == COLOR_SPEC_YUV_BT709)
+    convert->matrix16 = matrix16_yuv_bt709_to_yuv_bt470_6;
+  } else if (convert->from_spec == COLOR_SPEC_YUV_BT470_6
+      && convert->to_spec == COLOR_SPEC_YUV_BT709) {
     convert->matrix = matrix_yuv_bt470_6_to_yuv_bt709;
+    convert->matrix16 = matrix16_yuv_bt470_6_to_yuv_bt709;
+  }
 }
 
 static void
@@ -1311,10 +1676,18 @@ colorspace_convert_generic (ColorspaceConvert * convert, guint8 * dest,
     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);
+  if (convert->use_16bit) {
+    for (j = 0; j < convert->height; j++) {
+      convert->getline16 (convert, convert->tmpline16, src, j);
+      convert->matrix16 (convert);
+      convert->putline16 (convert, dest, convert->tmpline16, j);
+    }
+  } else {
+    for (j = 0; j < convert->height; j++) {
+      convert->getline (convert, convert->tmpline, src, j);
+      convert->matrix (convert);
+      convert->putline (convert, dest, convert->tmpline, j);
+    }
   }
 }
 
index b12b032..fe72524 100644 (file)
@@ -43,6 +43,7 @@ struct _ColorspaceComponent {
 struct _ColorspaceConvert {
   gint width, height;
   gboolean interlaced;
+  gboolean use_16bit;
 
   GstVideoFormat from_format;
   ColorSpaceColorSpec from_spec;
@@ -51,6 +52,7 @@ struct _ColorspaceConvert {
   guint32 *palette;
 
   guint8 *tmpline;
+  guint16 *tmpline16;
 
   int dest_offset[4];
   int dest_stride[4];
@@ -61,6 +63,10 @@ struct _ColorspaceConvert {
   void (*getline) (ColorspaceConvert *convert, guint8 *dest, const guint8 *src, int j);
   void (*putline) (ColorspaceConvert *convert, guint8 *dest, const guint8 *src, int j);
   void (*matrix) (ColorspaceConvert *convert);
+
+  void (*getline16) (ColorspaceConvert *convert, guint16 *dest, const guint8 *src, int j);
+  void (*putline16) (ColorspaceConvert *convert, guint8 *dest, const guint16 *src, int j);
+  void (*matrix16) (ColorspaceConvert *convert);
 };
 
 ColorspaceConvert * colorspace_convert_new (GstVideoFormat to_format,
index 508fb8a..350b6c2 100644 (file)
 #include "gstcolorspace.h"
 #include <gst/video/video.h>
 
-/* For GST_CHECK_PLUGINS_BASE_VERSION() */
-#include <gst/pbutils/pbutils.h>
-
 #include <string.h>
 
 GST_DEBUG_CATEGORY (colorspace_debug);
 #define GST_CAT_DEFAULT colorspace_debug
 GST_DEBUG_CATEGORY (colorspace_performance);
 
-#if GST_CHECK_PLUGINS_BASE_VERSION(0, 10, 32)
-#define VIDEO_CAPS_RGB8_PALETTED \
-  GST_VIDEO_CAPS_RGB8_PALETTED "; "
-#else
-#define VIDEO_CAPS_RGB8_PALETTED        /* no-op */
-#endif
-
 #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, v210, A420 } ;" \
+  "format= (fourcc) { I420 , NV12 , NV21 , YV12 , YUY2 , Y42B , Y444 , YUV9 , YVU9 , Y41B , Y800 , Y8 , GREY , Y16 , UYVY , YVYU , IYU1 , v308 , AYUV, v210, A420, AY64 } ;" \
   GST_VIDEO_CAPS_RGB";"                                                        \
   GST_VIDEO_CAPS_BGR";"                                                        \
   GST_VIDEO_CAPS_RGBx";"                                               \
@@ -74,10 +64,11 @@ GST_DEBUG_CATEGORY (colorspace_performance);
   GST_VIDEO_CAPS_BGR_16";"                                             \
   GST_VIDEO_CAPS_RGB_15";"                                             \
   GST_VIDEO_CAPS_BGR_15";"                                             \
-  VIDEO_CAPS_RGB8_PALETTED                                              \
+  GST_VIDEO_CAPS_RGB8_PALETTED "; "                                     \
   GST_VIDEO_CAPS_GRAY8";"                                              \
   GST_VIDEO_CAPS_GRAY16("BIG_ENDIAN")";"                               \
-  GST_VIDEO_CAPS_GRAY16("LITTLE_ENDIAN")";"
+  GST_VIDEO_CAPS_GRAY16("LITTLE_ENDIAN")";"                             \
+  GST_VIDEO_CAPS_ARGB_64
 
 static GstStaticPadTemplate gst_csp_src_template =
 GST_STATIC_PAD_TEMPLATE ("src",
@@ -319,7 +310,6 @@ gst_csp_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
   if (space->convert) {
     colorspace_convert_set_interlaced (space->convert, in_interlaced);
   }
-#if GST_CHECK_PLUGINS_BASE_VERSION(0, 10, 32)
   /* palette, only for from data */
   if (space->from_format == GST_VIDEO_FORMAT_RGB8_PALETTED &&
       space->to_format == GST_VIDEO_FORMAT_RGB8_PALETTED) {
@@ -347,7 +337,6 @@ gst_csp_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
     gst_caps_set_simple (outcaps, "palette_data", GST_TYPE_BUFFER, p_buf, NULL);
     gst_buffer_unref (p_buf);
   }
-#endif
 
   GST_DEBUG ("reconfigured %d %d", space->from_format, space->to_format);
 
@@ -375,7 +364,6 @@ format_mismatch:
     space->to_format = GST_VIDEO_FORMAT_UNKNOWN;
     return FALSE;
   }
-#if GST_CHECK_PLUGINS_BASE_VERSION(0, 10, 32)
 invalid_palette:
   {
     GST_ERROR_OBJECT (space, "invalid palette");
@@ -383,7 +371,6 @@ invalid_palette:
     space->to_format = GST_VIDEO_FORMAT_UNKNOWN;
     return FALSE;
   }
-#endif
 }
 
 GST_BOILERPLATE (GstCsp, gst_csp, GstVideoFilter, GST_TYPE_VIDEO_FILTER);