colorspace: Add 16-bit-per-channel handling

This commit is contained in:
David Schleef 2011-02-19 13:12:41 -08:00
parent 3192e69c0c
commit 6fcdba78a8
4 changed files with 436 additions and 70 deletions

View file

@ -51,7 +51,7 @@ AM_PROG_LIBTOOL
dnl *** required versions of GStreamer stuff ***
GST_REQ=0.10.32.1
GSTPB_REQ=0.10.32
GSTPB_REQ=0.10.32.1
dnl *** autotools stuff ****

View 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;
}
}
@ -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);
}
}
}

View 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,

View file

@ -40,26 +40,16 @@
#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);