cog: Add color matrix to RGB->YCbCr conversion

This commit is contained in:
David Schleef 2009-10-08 15:18:04 -07:00
parent a4c24b9222
commit 277699bd2a
6 changed files with 82 additions and 40 deletions

View file

@ -386,7 +386,7 @@ convsuswb d1, t3
.param 2 p3
.param 2 p4
.param 2 p5
.param 2 p6
#.param 2 p6
.temp 2 t1
.temp 2 t2
#.temp 2 t3
@ -402,8 +402,8 @@ mullw t2, t2, p3
addw t1, t1, t2
addw t1, t1, p4
shrsw t1, t1, p5
addw t1, t1, p6
convsuswb d1, t1
#addw t1, t1, p6
convwb d1, t1

View file

@ -1289,6 +1289,19 @@ cog_virt_frame_new_pack_RGB (CogFrame * vf)
return virt_frame;
}
static const int cog_rgb_to_ycbcr_matrix_8bit_sdtv[] = {
66, 129, 25, 4096,
-38, -74, 112, 32768,
112, -94, -18, 32768,
};
static const int cog_rgb_to_ycbcr_matrix_8bit_hdtv[] = {
47, 157, 16, 4096,
-26, -87, 112, 32768,
112, -102, -10, 32768,
};
static void
color_matrix_RGB_to_YCbCr (CogFrame * frame, void *_dest, int component, int i)
{
@ -1296,6 +1309,7 @@ color_matrix_RGB_to_YCbCr (CogFrame * frame, void *_dest, int component, int i)
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);
@ -1304,25 +1318,16 @@ color_matrix_RGB_to_YCbCr (CogFrame * frame, void *_dest, int component, int i)
/* for RGB -> YUV */
switch (component) {
case 0:
/* m1 = 0.25679;
* m2 = 0.50413;
* m3 = 0.097906; */
orc_matrix3_000_u8 (dest, src1, src2, src3,
66, 129, 25, 128, 8, 16, frame->width);
matrix[0], matrix[1], matrix[2], (16 << 8) + 128, 8, frame->width);
break;
case 1:
/* m1 = -0.14822;
* m2 = -0.29099;
* m3 = 0.43922; */
orc_matrix3_000_u8 (dest, src1, src2, src3,
-37, -74, 112, 128, 8, 128, frame->width);
matrix[4], matrix[5], matrix[6], (128 << 8) + 128, 8, frame->width);
break;
case 2:
/* m1 = 0.43922;
* m2 = -0.36779;
* m3 = -0.071427; */
orc_matrix3_000_u8 (dest, src1, src2, src3,
112, -94, 18, 128, 8, 128, frame->width);
matrix[8], matrix[9], matrix[10], (128 << 8) + 128, 8, frame->width);
break;
default:
break;
@ -1371,23 +1376,14 @@ color_matrix_YCbCr_to_RGB_6bit (CogFrame * frame, void *_dest, int component,
switch (component) {
case 0:
/* m1 = 1.1644;
* m2 = 0;
* m3 = 1.596; */
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, 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,
matrix[8], matrix[9], matrix[11] + 32, frame->width);
break;
@ -1412,24 +1408,14 @@ 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,
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,
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,
matrix[8], matrix[9], 128, 8, frame->width);
break;
@ -1469,7 +1455,7 @@ cog_virt_frame_new_color_matrix_YCbCr_to_RGB (CogFrame * vf,
CogFrame *
cog_virt_frame_new_color_matrix_RGB_to_YCbCr (CogFrame * vf,
CogColorMatrix color_matrix)
CogColorMatrix color_matrix, int coefficient_bits)
{
CogFrame *virt_frame;
@ -1477,7 +1463,11 @@ 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;
if (color_matrix == COG_COLOR_MATRIX_HDTV) {
virt_frame->virt_priv2 = (void *) cog_rgb_to_ycbcr_matrix_8bit_hdtv;
} else {
virt_frame->virt_priv2 = (void *) cog_rgb_to_ycbcr_matrix_8bit_sdtv;
}
return virt_frame;
}

View file

@ -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, 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_color_matrix_YCbCr_to_RGB (CogFrame *vf, CogColorMatrix color_matrix, int coefficient_bits);
CogFrame * cog_virt_frame_new_color_matrix_RGB_to_YCbCr (CogFrame * vf, CogColorMatrix color_matrix, int coefficient_bits);
CogFrame *cog_virt_frame_new_subsample (CogFrame *vf, CogFrameFormat format);
CogFrame * cog_virt_frame_new_convert_u8 (CogFrame *vf);

View file

@ -129,6 +129,57 @@ main (int argc, char *argv[])
}
}
{
int cm, bits;
for (cm = 0; cm < 2; cm++) {
for (bits = 8; bits <= 8; bits += 1) {
ColorMatrix matrix;
color_matrix_set_identity (&matrix);
color_matrix_scale_components (&matrix, (1 / 255.0), (1 / 255.0),
(1 / 255.0));
/* colour matrix, RGB -> YCbCr */
if (cm) {
color_matrix_RGB_to_YCbCr (&matrix, 0.2126, 0.0722); /* HD */
} else {
color_matrix_RGB_to_YCbCr (&matrix, 0.2990, 0.1140); /* SD */
}
/*
* We are now in YCbCr space
*/
color_matrix_scale_components (&matrix, 219.0, 224.0, 224.0);
color_matrix_offset_components (&matrix, 16, 128, 128);
/* 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_rgb_to_ycbcr_matrix_%dbit_%s[] = {\n",
bits, cm ? "hdtv" : "sdtv");
g_print (" %d, %d, %d, %d,\n",
(int) rint (matrix.m[0][0]),
(int) rint (matrix.m[0][1]),
(int) rint (matrix.m[0][2]), (int) rint (matrix.m[0][3]));
g_print (" %d, %d, %d, %d,\n",
(int) rint (matrix.m[1][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]),
(int) rint (matrix.m[2][1]),
(int) rint (matrix.m[2][2]), (int) rint (matrix.m[2][3]));
g_print ("};\n");
}
}
}
return 0;
}

View file

@ -445,7 +445,7 @@ 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,
compress->color_matrix);
compress->color_matrix, 8);
}
frame = cog_virt_frame_new_subsample (frame, new_subsample);

View file

@ -265,7 +265,8 @@ 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, COG_COLOR_MATRIX_SDTV);
f = cog_virt_frame_new_color_matrix_RGB_to_YCbCr (f, COG_COLOR_MATRIX_SDTV,
8);
f = cog_virt_frame_new_subsample (f, frame->format);
li->overlay_frame = cog_frame_realize (f);
}