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 p3
.param 2 p4 .param 2 p4
.param 2 p5 .param 2 p5
.param 2 p6 #.param 2 p6
.temp 2 t1 .temp 2 t1
.temp 2 t2 .temp 2 t2
#.temp 2 t3 #.temp 2 t3
@ -402,8 +402,8 @@ mullw t2, t2, p3
addw t1, t1, t2 addw t1, t1, t2
addw t1, t1, p4 addw t1, t1, p4
shrsw t1, t1, p5 shrsw t1, t1, p5
addw t1, t1, p6 #addw t1, t1, p6
convsuswb d1, t1 convwb d1, t1

View file

@ -1289,6 +1289,19 @@ cog_virt_frame_new_pack_RGB (CogFrame * vf)
return virt_frame; 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 static void
color_matrix_RGB_to_YCbCr (CogFrame * frame, void *_dest, int component, int i) 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 *src1;
uint8_t *src2; uint8_t *src2;
uint8_t *src3; uint8_t *src3;
int *matrix = frame->virt_priv2;
src1 = cog_virt_frame_get_line (frame->virt_frame1, 0, i); src1 = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
src2 = cog_virt_frame_get_line (frame->virt_frame1, 1, 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 */ /* for RGB -> YUV */
switch (component) { switch (component) {
case 0: case 0:
/* m1 = 0.25679;
* m2 = 0.50413;
* m3 = 0.097906; */
orc_matrix3_000_u8 (dest, src1, src2, src3, 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; break;
case 1: case 1:
/* m1 = -0.14822;
* m2 = -0.29099;
* m3 = 0.43922; */
orc_matrix3_000_u8 (dest, src1, src2, src3, 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; break;
case 2: case 2:
/* m1 = 0.43922;
* m2 = -0.36779;
* m3 = -0.071427; */
orc_matrix3_000_u8 (dest, src1, src2, src3, 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; break;
default: default:
break; break;
@ -1371,23 +1376,14 @@ color_matrix_YCbCr_to_RGB_6bit (CogFrame * frame, void *_dest, int component,
switch (component) { switch (component) {
case 0: case 0:
/* m1 = 1.1644;
* m2 = 0;
* m3 = 1.596; */
orc_matrix2_u8 (dest, src1, src3, matrix[0], matrix[2], matrix[3] + 32, orc_matrix2_u8 (dest, src1, src3, matrix[0], matrix[2], matrix[3] + 32,
frame->width); frame->width);
break; break;
case 1: case 1:
/* m1 = 1.1644;
* m2 = -0.39176;
* m3 = -0.81297; */
orc_matrix3_u8 (dest, src1, src2, src3, matrix[4], matrix[5], matrix[6], orc_matrix3_u8 (dest, src1, src2, src3, matrix[4], matrix[5], matrix[6],
matrix[7] + 32, frame->width); matrix[7] + 32, frame->width);
break; break;
case 2: case 2:
/* m1 = 1.1644;
* m2 = 2.0172;
* m3 = 0; */
orc_matrix2_u8 (dest, src1, src2, orc_matrix2_u8 (dest, src1, src2,
matrix[8], matrix[9], matrix[11] + 32, frame->width); matrix[8], matrix[9], matrix[11] + 32, frame->width);
break; break;
@ -1412,24 +1408,14 @@ color_matrix_YCbCr_to_RGB_8bit (CogFrame * frame, void *_dest, int component,
switch (component) { switch (component) {
case 0: case 0:
/* m1 = 1.1644;
* m2 = 0;
* m3 = 1.596; */
orc_matrix2_11_u8 (dest, src1, src3, orc_matrix2_11_u8 (dest, src1, src3,
matrix[0], matrix[2], 128, 8, frame->width); matrix[0], matrix[2], 128, 8, frame->width);
break; break;
case 1: case 1:
/* m1 = 1.1644;
* m2 = -0.39176;
* m3 = -0.81297; */
orc_matrix3_100_u8 (dest, src1, src2, src3, orc_matrix3_100_u8 (dest, src1, src2, src3,
matrix[4], matrix[5], matrix[6], 128, 8, frame->width); matrix[4], matrix[5], matrix[6], 128, 8, frame->width);
break; break;
case 2: case 2:
/* m1 = 1.1644;
* m2 = 2.0172;
* m3 = 0; */
orc_matrix2_12_u8 (dest, src1, src2, orc_matrix2_12_u8 (dest, src1, src2,
matrix[8], matrix[9], 128, 8, frame->width); matrix[8], matrix[9], 128, 8, frame->width);
break; break;
@ -1469,7 +1455,7 @@ cog_virt_frame_new_color_matrix_YCbCr_to_RGB (CogFrame * vf,
CogFrame * 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) CogColorMatrix color_matrix, int coefficient_bits)
{ {
CogFrame *virt_frame; CogFrame *virt_frame;
@ -1477,7 +1463,11 @@ cog_virt_frame_new_color_matrix_RGB_to_YCbCr (CogFrame * vf,
vf->width, vf->height); vf->width, vf->height);
virt_frame->virt_frame1 = vf; virt_frame->virt_frame1 = vf;
virt_frame->render_line = color_matrix_RGB_to_YCbCr; 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; 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_v216 (CogFrame *vf);
CogFrame *cog_virt_frame_new_pack_v210 (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_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_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); 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_subsample (CogFrame *vf, CogFrameFormat format);
CogFrame * cog_virt_frame_new_convert_u8 (CogFrame *vf); 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; return 0;
} }

View file

@ -445,7 +445,7 @@ gst_cogcolorspace_transform (GstBaseTransform * base_transform,
if (gst_video_format_is_yuv (out_format) && if (gst_video_format_is_yuv (out_format) &&
gst_video_format_is_rgb (in_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); compress->color_matrix, 8);
} }
frame = cog_virt_frame_new_subsample (frame, new_subsample); 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); li->alpha_frame = cog_frame_realize (f);
f = cog_virt_frame_new_unpack (cog_frame_ref (li->ayuv_frame)); 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); f = cog_virt_frame_new_subsample (f, frame->format);
li->overlay_frame = cog_frame_realize (f); li->overlay_frame = cog_frame_realize (f);
} }