diff --git a/gst/colorspace/colorspace.c b/gst/colorspace/colorspace.c index e69ab80a4b..b949fe28f3 100644 --- a/gst/colorspace/colorspace.c +++ b/gst/colorspace/colorspace.c @@ -27,8 +27,6 @@ #include #include "gstcolorspaceorc.h" -/* For GST_CHECK_PLUGINS_BASE_VERSION() */ -#include 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; } } @@ -445,6 +554,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); + } } } diff --git a/gst/colorspace/colorspace.h b/gst/colorspace/colorspace.h index b12b032df9..fe72524dde 100644 --- a/gst/colorspace/colorspace.h +++ b/gst/colorspace/colorspace.h @@ -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, diff --git a/gst/colorspace/gstcolorspace.c b/gst/colorspace/gstcolorspace.c index 508fb8a708..350b6c23ea 100644 --- a/gst/colorspace/gstcolorspace.c +++ b/gst/colorspace/gstcolorspace.c @@ -40,26 +40,16 @@ #include "gstcolorspace.h" #include -/* For GST_CHECK_PLUGINS_BASE_VERSION() */ -#include - #include 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);