mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-11 19:06:33 +00:00
cog: Add color matrix selection to cogcolorspace
Eventually hook it up to caps via gstvideo
This commit is contained in:
parent
4ee3afc051
commit
a4c24b9222
7 changed files with 169 additions and 37 deletions
|
@ -36,6 +36,7 @@ libgstcog_la_SOURCES = \
|
|||
gstcms.c
|
||||
|
||||
noinst_PROGRAMS = generate_tables
|
||||
generate_tables_SOURCES = generate_tables.c gstcms.c
|
||||
generate_tables_CFLAGS = $(GST_CFLAGS)
|
||||
generate_tables_LDADD = $(GST_LIBS)
|
||||
|
||||
|
|
|
@ -13,6 +13,12 @@ typedef struct _CogUpsampledFrame CogUpsampledFrame;
|
|||
typedef void (*CogFrameFreeFunc)(CogFrame *frame, void *priv);
|
||||
typedef void (*CogFrameRenderFunc)(CogFrame *frame, void *dest, int component, int i);
|
||||
|
||||
typedef enum _CogColorMatrix {
|
||||
COG_COLOR_MATRIX_UNKNOWN = 0,
|
||||
COG_COLOR_MATRIX_HDTV,
|
||||
COG_COLOR_MATRIX_SDTV
|
||||
} CogColorMatrix;
|
||||
|
||||
/* bit pattern:
|
||||
* 0x100 - 0: normal, 1: indirect (packed)
|
||||
* 0x001 - horizontal chroma subsampling: 0: 1, 1: 2
|
||||
|
|
|
@ -1330,6 +1330,31 @@ color_matrix_RGB_to_YCbCr (CogFrame * frame, void *_dest, int component, int i)
|
|||
|
||||
}
|
||||
|
||||
|
||||
static const int cog_ycbcr_to_rgb_matrix_6bit_sdtv[] = {
|
||||
75, 0, 102, -14267,
|
||||
75, -25, -52, 8677,
|
||||
75, 129, 0, -17717,
|
||||
};
|
||||
|
||||
static const int cog_ycbcr_to_rgb_matrix_8bit_sdtv[] = {
|
||||
42, 0, 153, -57068,
|
||||
42, -100, -208, 34707,
|
||||
42, 4, 0, -70870,
|
||||
};
|
||||
|
||||
static const int cog_ycbcr_to_rgb_matrix_6bit_hdtv[] = {
|
||||
75, 0, 115, -15878,
|
||||
75, -14, -34, 4920,
|
||||
75, 135, 0, -18497,
|
||||
};
|
||||
|
||||
static const int cog_ycbcr_to_rgb_matrix_8bit_hdtv[] = {
|
||||
42, 0, 203, -63514,
|
||||
42, -55, -136, 19681,
|
||||
42, 29, 0, -73988,
|
||||
};
|
||||
|
||||
static void
|
||||
color_matrix_YCbCr_to_RGB_6bit (CogFrame * frame, void *_dest, int component,
|
||||
int i)
|
||||
|
@ -1338,6 +1363,7 @@ color_matrix_YCbCr_to_RGB_6bit (CogFrame * frame, void *_dest, int component,
|
|||
uint8_t *src1;
|
||||
uint8_t *src2;
|
||||
uint8_t *src3;
|
||||
int *matrix = frame->virt_priv2;
|
||||
|
||||
src1 = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
|
||||
src2 = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
|
||||
|
@ -1348,20 +1374,22 @@ color_matrix_YCbCr_to_RGB_6bit (CogFrame * frame, void *_dest, int component,
|
|||
/* m1 = 1.1644;
|
||||
* m2 = 0;
|
||||
* m3 = 1.596; */
|
||||
orc_matrix2_u8 (dest, src1, src3, 75, 102, -14269 + 32, frame->width);
|
||||
orc_matrix2_u8 (dest, src1, src3, matrix[0], matrix[2], matrix[3] + 32,
|
||||
frame->width);
|
||||
break;
|
||||
case 1:
|
||||
/* m1 = 1.1644;
|
||||
* m2 = -0.39176;
|
||||
* m3 = -0.81297; */
|
||||
orc_matrix3_u8 (dest, src1, src2, src3, 75, -25, -52, 8677 + 32,
|
||||
frame->width);
|
||||
orc_matrix3_u8 (dest, src1, src2, src3, matrix[4], matrix[5], matrix[6],
|
||||
matrix[7] + 32, frame->width);
|
||||
break;
|
||||
case 2:
|
||||
/* m1 = 1.1644;
|
||||
* m2 = 2.0172;
|
||||
* m3 = 0; */
|
||||
orc_matrix2_u8 (dest, src1, src2, 75, 129, -17718 + 32, frame->width);
|
||||
orc_matrix2_u8 (dest, src1, src2,
|
||||
matrix[8], matrix[9], matrix[11] + 32, frame->width);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1376,6 +1404,7 @@ color_matrix_YCbCr_to_RGB_8bit (CogFrame * frame, void *_dest, int component,
|
|||
uint8_t *src1;
|
||||
uint8_t *src2;
|
||||
uint8_t *src3;
|
||||
int *matrix = frame->virt_priv2;
|
||||
|
||||
src1 = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
|
||||
src2 = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
|
||||
|
@ -1383,23 +1412,26 @@ color_matrix_YCbCr_to_RGB_8bit (CogFrame * frame, void *_dest, int component,
|
|||
|
||||
switch (component) {
|
||||
case 0:
|
||||
|
||||
/* m1 = 1.1644;
|
||||
* m2 = 0;
|
||||
* m3 = 1.596; */
|
||||
orc_matrix2_11_u8 (dest, src1, src3, 42, 153, 128, 8, frame->width);
|
||||
orc_matrix2_11_u8 (dest, src1, src3,
|
||||
matrix[0], matrix[2], 128, 8, frame->width);
|
||||
break;
|
||||
case 1:
|
||||
/* m1 = 1.1644;
|
||||
* m2 = -0.39176;
|
||||
* m3 = -0.81297; */
|
||||
orc_matrix3_100_u8 (dest, src1, src2, src3, 42, -100, -208, 128, 8,
|
||||
frame->width);
|
||||
orc_matrix3_100_u8 (dest, src1, src2, src3,
|
||||
matrix[4], matrix[5], matrix[6], 128, 8, frame->width);
|
||||
break;
|
||||
case 2:
|
||||
/* m1 = 1.1644;
|
||||
* m2 = 2.0172;
|
||||
* m3 = 0; */
|
||||
orc_matrix2_12_u8 (dest, src1, src2, 42, 4, 128, 8, frame->width);
|
||||
orc_matrix2_12_u8 (dest, src1, src2,
|
||||
matrix[8], matrix[9], 128, 8, frame->width);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1407,24 +1439,37 @@ color_matrix_YCbCr_to_RGB_8bit (CogFrame * frame, void *_dest, int component,
|
|||
}
|
||||
|
||||
CogFrame *
|
||||
cog_virt_frame_new_color_matrix_YCbCr_to_RGB (CogFrame * vf, int bits)
|
||||
cog_virt_frame_new_color_matrix_YCbCr_to_RGB (CogFrame * vf,
|
||||
CogColorMatrix color_matrix, int bits)
|
||||
{
|
||||
CogFrame *virt_frame;
|
||||
//int *matrix = frame->virt_priv2;
|
||||
|
||||
virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_U8_444,
|
||||
vf->width, vf->height);
|
||||
virt_frame->virt_frame1 = vf;
|
||||
if (bits <= 6) {
|
||||
virt_frame->render_line = color_matrix_YCbCr_to_RGB_6bit;
|
||||
if (color_matrix == COG_COLOR_MATRIX_HDTV) {
|
||||
virt_frame->virt_priv2 = (void *) cog_ycbcr_to_rgb_matrix_6bit_hdtv;
|
||||
} else {
|
||||
virt_frame->virt_priv2 = (void *) cog_ycbcr_to_rgb_matrix_6bit_sdtv;
|
||||
}
|
||||
} else {
|
||||
virt_frame->render_line = color_matrix_YCbCr_to_RGB_8bit;
|
||||
if (color_matrix == COG_COLOR_MATRIX_HDTV) {
|
||||
virt_frame->virt_priv2 = (void *) cog_ycbcr_to_rgb_matrix_8bit_hdtv;
|
||||
} else {
|
||||
virt_frame->virt_priv2 = (void *) cog_ycbcr_to_rgb_matrix_8bit_sdtv;
|
||||
}
|
||||
}
|
||||
|
||||
return virt_frame;
|
||||
}
|
||||
|
||||
CogFrame *
|
||||
cog_virt_frame_new_color_matrix_RGB_to_YCbCr (CogFrame * vf)
|
||||
cog_virt_frame_new_color_matrix_RGB_to_YCbCr (CogFrame * vf,
|
||||
CogColorMatrix color_matrix)
|
||||
{
|
||||
CogFrame *virt_frame;
|
||||
|
||||
|
@ -1432,6 +1477,7 @@ cog_virt_frame_new_color_matrix_RGB_to_YCbCr (CogFrame * vf)
|
|||
vf->width, vf->height);
|
||||
virt_frame->virt_frame1 = vf;
|
||||
virt_frame->render_line = color_matrix_RGB_to_YCbCr;
|
||||
virt_frame->param1 = color_matrix;
|
||||
|
||||
return virt_frame;
|
||||
}
|
||||
|
|
|
@ -27,8 +27,8 @@ CogFrame *cog_virt_frame_new_pack_AYUV (CogFrame *vf);
|
|||
CogFrame *cog_virt_frame_new_pack_v216 (CogFrame *vf);
|
||||
CogFrame *cog_virt_frame_new_pack_v210 (CogFrame *vf);
|
||||
CogFrame *cog_virt_frame_new_pack_RGB (CogFrame *vf);
|
||||
CogFrame *cog_virt_frame_new_color_matrix_YCbCr_to_RGB (CogFrame *vf, int bits);
|
||||
CogFrame * cog_virt_frame_new_color_matrix_RGB_to_YCbCr (CogFrame * vf);
|
||||
CogFrame *cog_virt_frame_new_color_matrix_YCbCr_to_RGB (CogFrame *vf, CogColorMatrix color_matrix, int bits);
|
||||
CogFrame * cog_virt_frame_new_color_matrix_RGB_to_YCbCr (CogFrame * vf, CogColorMatrix color_matrix);
|
||||
CogFrame *cog_virt_frame_new_subsample (CogFrame *vf, CogFrameFormat format);
|
||||
|
||||
CogFrame * cog_virt_frame_new_convert_u8 (CogFrame *vf);
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <glib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "gstcms.h"
|
||||
|
||||
#define SCALE 256
|
||||
|
||||
void
|
||||
|
@ -66,5 +68,67 @@ main (int argc, char *argv[])
|
|||
g_print ("};\n");
|
||||
g_print ("\n");
|
||||
|
||||
|
||||
{
|
||||
int cm, bits;
|
||||
|
||||
for (cm = 0; cm < 2; cm++) {
|
||||
for (bits = 6; bits <= 8; bits += 2) {
|
||||
|
||||
ColorMatrix matrix;
|
||||
|
||||
/*
|
||||
* At this point, everything is in YCbCr
|
||||
* All components are in the range [0,255]
|
||||
*/
|
||||
color_matrix_set_identity (&matrix);
|
||||
|
||||
/* offset required to get input video black to (0.,0.,0.) */
|
||||
/* we don't do this because the code does it for us */
|
||||
color_matrix_offset_components (&matrix, -16, -128, -128);
|
||||
|
||||
color_matrix_scale_components (&matrix, (1 / 219.0), (1 / 224.0),
|
||||
(1 / 224.0));
|
||||
|
||||
/* colour matrix, YCbCr -> RGB */
|
||||
/* Requires Y in [0,1.0], Cb&Cr in [-0.5,0.5] */
|
||||
if (cm) {
|
||||
color_matrix_YCbCr_to_RGB (&matrix, 0.2126, 0.0722); /* HD */
|
||||
} else {
|
||||
color_matrix_YCbCr_to_RGB (&matrix, 0.2990, 0.1140); /* SD */
|
||||
}
|
||||
|
||||
/*
|
||||
* We are now in RGB space
|
||||
*/
|
||||
|
||||
/* scale to output range. */
|
||||
color_matrix_scale_components (&matrix, 255.0, 255.0, 255.0);
|
||||
|
||||
/* because we're doing 8-bit matrix coefficients */
|
||||
color_matrix_scale_components (&matrix, 1 << bits, 1 << bits,
|
||||
1 << bits);
|
||||
|
||||
g_print ("static const int cog_ycbcr_to_rgb_matrix_%dbit_%s[] = {\n",
|
||||
bits, cm ? "hdtv" : "sdtv");
|
||||
g_print (" %d, %d, %d, %d,\n",
|
||||
(int) rint (matrix.m[0][0] - ((bits == 8) ? 256 : 0)),
|
||||
(int) rint (matrix.m[0][1]),
|
||||
(int) rint (matrix.m[0][2] - ((bits == 8) ? 256 : 0)),
|
||||
(int) rint (matrix.m[0][3]));
|
||||
g_print (" %d, %d, %d, %d,\n",
|
||||
(int) rint (matrix.m[1][0] - ((bits == 8) ? 256 : 0)),
|
||||
(int) rint (matrix.m[1][1]),
|
||||
(int) rint (matrix.m[1][2]), (int) rint (matrix.m[1][3]));
|
||||
g_print (" %d, %d, %d, %d,\n",
|
||||
(int) rint (matrix.m[2][0] - ((bits == 8) ? 256 : 0)),
|
||||
(int) rint (matrix.m[2][1] - ((bits == 8) ? 512 : 0)),
|
||||
(int) rint (matrix.m[2][2]), (int) rint (matrix.m[2][3]));
|
||||
g_print ("};\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ struct _GstCogcolorspace
|
|||
GstBaseTransform base_transform;
|
||||
|
||||
int quality;
|
||||
CogColorMatrix color_matrix;
|
||||
};
|
||||
|
||||
struct _GstCogcolorspaceClass
|
||||
|
@ -75,11 +76,13 @@ enum
|
|||
};
|
||||
|
||||
#define DEFAULT_QUALITY 5
|
||||
#define DEFAULT_COLOR_MATRIX COG_COLOR_MATRIX_UNKNOWN
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_QUALITY
|
||||
PROP_QUALITY,
|
||||
PROP_COLOR_MATRIX
|
||||
};
|
||||
|
||||
static void gst_cogcolorspace_set_property (GObject * object, guint prop_id,
|
||||
|
@ -119,31 +122,26 @@ static GstStaticPadTemplate gst_cogcolorspace_src_template =
|
|||
GST_BOILERPLATE (GstCogcolorspace, gst_cogcolorspace, GstBaseTransform,
|
||||
GST_TYPE_BASE_TRANSFORM);
|
||||
|
||||
#if 0
|
||||
GType
|
||||
gst_cogcolorspace_get_type (void)
|
||||
gst_cog_color_matrix_get_type (void)
|
||||
{
|
||||
static GType compress_type = 0;
|
||||
static gsize id = 0;
|
||||
static const GEnumValue values[] = {
|
||||
{COG_COLOR_MATRIX_UNKNOWN, "unknown",
|
||||
"Unknown color matrix (works like sdtv)"},
|
||||
{COG_COLOR_MATRIX_HDTV, "hdtv", "High Definition TV color matrix (BT.709)"},
|
||||
{COG_COLOR_MATRIX_SDTV, "sdtv",
|
||||
"Standard Definition TV color matrix (BT.470)"},
|
||||
{0, NULL, NULL}
|
||||
};
|
||||
|
||||
if (!compress_type) {
|
||||
static const GTypeInfo compress_info = {
|
||||
sizeof (GstCogcolorspaceClass),
|
||||
gst_cogcolorspace_base_init,
|
||||
NULL,
|
||||
gst_cogcolorspace_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstCogcolorspace),
|
||||
0,
|
||||
gst_cogcolorspace_init,
|
||||
};
|
||||
|
||||
compress_type = g_type_register_static (GST_TYPE_BASE_TRANSFORM,
|
||||
"GstCogcolorspace", &compress_info, 0);
|
||||
if (g_once_init_enter (&id)) {
|
||||
GType tmp = g_enum_register_static ("CogColorMatrix", values);
|
||||
g_once_init_leave (&id, tmp);
|
||||
}
|
||||
return compress_type;
|
||||
|
||||
return (GType) id;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
gst_cogcolorspace_base_init (gpointer g_class)
|
||||
|
@ -178,7 +176,12 @@ gst_cogcolorspace_class_init (GstCogcolorspaceClass * colorspace_class)
|
|||
|
||||
g_object_class_install_property (gobject_class, PROP_QUALITY,
|
||||
g_param_spec_int ("quality", "Quality", "Quality",
|
||||
0, 10, DEFAULT_QUALITY, G_PARAM_READWRITE));
|
||||
0, 10, DEFAULT_QUALITY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gobject_class, PROP_COLOR_MATRIX,
|
||||
g_param_spec_enum ("color-matrix", "Color Matrix",
|
||||
"Color matrix for YCbCr <-> RGB conversion",
|
||||
gst_cog_color_matrix_get_type (),
|
||||
DEFAULT_COLOR_MATRIX, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
base_transform_class->transform = gst_cogcolorspace_transform;
|
||||
base_transform_class->transform_caps = gst_cogcolorspace_transform_caps;
|
||||
|
@ -194,6 +197,7 @@ gst_cogcolorspace_init (GstCogcolorspace * colorspace,
|
|||
GST_DEBUG ("gst_cogcolorspace_init");
|
||||
|
||||
colorspace->quality = DEFAULT_QUALITY;
|
||||
colorspace->color_matrix = DEFAULT_COLOR_MATRIX;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -212,6 +216,11 @@ gst_cogcolorspace_set_property (GObject * object, guint prop_id,
|
|||
colorspace->quality = g_value_get_int (value);
|
||||
GST_OBJECT_UNLOCK (colorspace);
|
||||
break;
|
||||
case PROP_COLOR_MATRIX:
|
||||
GST_OBJECT_LOCK (colorspace);
|
||||
colorspace->color_matrix = g_value_get_enum (value);
|
||||
GST_OBJECT_UNLOCK (colorspace);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -232,6 +241,11 @@ gst_cogcolorspace_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
g_value_set_int (value, colorspace->quality);
|
||||
GST_OBJECT_UNLOCK (colorspace);
|
||||
break;
|
||||
case PROP_COLOR_MATRIX:
|
||||
GST_OBJECT_LOCK (colorspace);
|
||||
g_value_set_enum (value, colorspace->color_matrix);
|
||||
GST_OBJECT_UNLOCK (colorspace);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -430,7 +444,8 @@ gst_cogcolorspace_transform (GstBaseTransform * base_transform,
|
|||
|
||||
if (gst_video_format_is_yuv (out_format) &&
|
||||
gst_video_format_is_rgb (in_format)) {
|
||||
frame = cog_virt_frame_new_color_matrix_RGB_to_YCbCr (frame);
|
||||
frame = cog_virt_frame_new_color_matrix_RGB_to_YCbCr (frame,
|
||||
compress->color_matrix);
|
||||
}
|
||||
|
||||
frame = cog_virt_frame_new_subsample (frame, new_subsample);
|
||||
|
@ -438,7 +453,7 @@ gst_cogcolorspace_transform (GstBaseTransform * base_transform,
|
|||
if (gst_video_format_is_rgb (out_format) &&
|
||||
gst_video_format_is_yuv (in_format)) {
|
||||
frame = cog_virt_frame_new_color_matrix_YCbCr_to_RGB (frame,
|
||||
(compress->quality > 5) ? 8 : 6);
|
||||
compress->color_matrix, (compress->quality >= 5) ? 8 : 6);
|
||||
}
|
||||
|
||||
switch (out_format) {
|
||||
|
|
|
@ -265,7 +265,7 @@ gst_logoinsert_transform_ip (GstBaseTransform * base_transform, GstBuffer * buf)
|
|||
li->alpha_frame = cog_frame_realize (f);
|
||||
|
||||
f = cog_virt_frame_new_unpack (cog_frame_ref (li->ayuv_frame));
|
||||
f = cog_virt_frame_new_color_matrix_RGB_to_YCbCr (f);
|
||||
f = cog_virt_frame_new_color_matrix_RGB_to_YCbCr (f, COG_COLOR_MATRIX_SDTV);
|
||||
f = cog_virt_frame_new_subsample (f, frame->format);
|
||||
li->overlay_frame = cog_frame_realize (f);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue