mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
colorspace: Add 16-bit-per-channel handling
This commit is contained in:
parent
3192e69c0c
commit
6fcdba78a8
4 changed files with 436 additions and 70 deletions
|
@ -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 ****
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue