cog: Improve RGB<->YCbCr matrixing

YCbCr->RGB now has a 'bits' setting, which controls the number
of bits used for the matrix coefficients.  Choices are 6 or 8.
6 is low quality, but faster.
RGB->YCbCr now works.  Always works in 8 bit, since it's the same
speed as 6 bit.
This commit is contained in:
David Schleef 2009-10-08 13:24:36 -07:00
parent 26ab6d772a
commit 4ee3afc051
4 changed files with 157 additions and 66 deletions

View file

@ -264,7 +264,7 @@ shrsw t1, t1, 6
convsuswb d1, t1
.function orc_matrix2_2_u8
.function orc_matrix2_11_u8
.dest 1 d1 uint8_t
.source 1 s1 uint8_t
.source 1 s2 uint8_t
@ -274,17 +274,49 @@ convsuswb d1, t1
.param 2 p4
.temp 2 t1
.temp 2 t2
.temp 2 t3
.temp 2 t4
convubw t1, s1
subw t1, t1, 16
mullw t1, t1, p1
mullw t3, t1, p1
convubw t2, s2
subw t2, t2, 128
mullw t2, t2, p2
addw t1, t1, t2
addw t1, t1, p3
shrsw t1, t1, p4
convsuswb d1, t1
mullw t4, t2, p2
addw t3, t3, t4
addw t3, t3, p3
shrsw t3, t3, p4
addw t3, t3, t1
addw t3, t3, t2
convsuswb d1, t3
.function orc_matrix2_12_u8
.dest 1 d1 uint8_t
.source 1 s1 uint8_t
.source 1 s2 uint8_t
.param 2 p1
.param 2 p2
.param 2 p3
.param 2 p4
.temp 2 t1
.temp 2 t2
.temp 2 t3
.temp 2 t4
convubw t1, s1
subw t1, t1, 16
mullw t3, t1, p1
convubw t2, s2
subw t2, t2, 128
mullw t4, t2, p2
addw t3, t3, t4
addw t3, t3, p3
shrsw t3, t3, p4
addw t3, t3, t1
addw t3, t3, t2
addw t3, t3, t2
convsuswb d1, t3
.function orc_matrix3_u8
@ -312,7 +344,7 @@ shrsw t1, t1, 6
convsuswb d1, t1
.function orc_matrix3_2_u8
.function orc_matrix3_100_u8
.dest 1 d1 uint8_t
.source 1 s1 uint8_t
.source 1 s2 uint8_t
@ -324,20 +356,53 @@ convsuswb d1, t1
.param 2 p5
.temp 2 t1
.temp 2 t2
.temp 2 t3
#.temp 2 t4
convubw t1, s1
subw t1, t1, 16
mullw t1, t1, p1
mullw t3, t1, p1
convubw t2, s2
subw t2, t2, 128
mullw t2, t2, p2
addw t1, t1, t2
addw t3, t3, t2
convubw t2, s3
subw t2, t2, 128
mullw t2, t2, p3
addw t3, t3, t2
addw t3, t3, p4
shrsw t3, t3, p5
addw t3, t3, t1
convsuswb d1, t3
.function orc_matrix3_000_u8
.dest 1 d1 uint8_t
.source 1 s1 uint8_t
.source 1 s2 uint8_t
.source 1 s3 uint8_t
.param 2 p1
.param 2 p2
.param 2 p3
.param 2 p4
.param 2 p5
.param 2 p6
.temp 2 t1
.temp 2 t2
#.temp 2 t3
#.temp 2 t4
convubw t1, s1
mullw t1, t1, p1
convubw t2, s2
mullw t2, t2, p2
addw t1, t1, t2
convubw t2, s3
mullw t2, t2, p3
addw t1, t1, t2
addw t1, t1, p4
shrsw t1, t1, p5
addw t1, t1, p6
convsuswb d1, t1

View file

@ -828,7 +828,7 @@ unpack_axyz (CogFrame * frame, void *_dest, int component, int i)
src = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
switch ((frame->param1>>(12-component*4))&0xf) {
switch ((frame->param1 >> (12 - component * 4)) & 0xf) {
case 0:
cogorc_unpack_axyz_0 (dest, src, frame->width);
break;
@ -1296,8 +1296,6 @@ color_matrix_RGB_to_YCbCr (CogFrame * frame, void *_dest, int component, int i)
uint8_t *src1;
uint8_t *src2;
uint8_t *src3;
double m1, m2, m3;
double offset;
src1 = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
src2 = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
@ -1306,45 +1304,40 @@ 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;
offset = 16;
orc_matrix3_u8 (dest, src1, src2, src3, 16, 32, 6, 16, frame->width);
/* 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);
break;
case 1:
m1 = -0.14822;
m2 = -0.29099;
m3 = 0.43922;
offset = 128;
orc_matrix3_u8 (dest, src1, src2, src3, -9, -19, 28, 128, frame->width);
/* 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);
break;
case 2:
m1 = 0.43922;
m2 = -0.36779;
m3 = -0.071427;
offset = 128;
orc_matrix3_u8 (dest, src1, src2, src3, 28, -24, -5, 128, frame->width);
/* 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);
break;
default:
m1 = 0.0;
m2 = 0.0;
m3 = 0.0;
offset = 0;
break;
}
}
static void
color_matrix_YCbCr_to_RGB (CogFrame * frame, void *_dest, int component, int i)
color_matrix_YCbCr_to_RGB_6bit (CogFrame * frame, void *_dest, int component,
int i)
{
uint8_t *dest = _dest;
uint8_t *src1;
uint8_t *src2;
uint8_t *src3;
double m1, m2, m3;
double offset;
src1 = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
src2 = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
@ -1352,50 +1345,80 @@ color_matrix_YCbCr_to_RGB (CogFrame * frame, void *_dest, int component, int i)
switch (component) {
case 0:
m1 = 1.1644;
m2 = 0;
m3 = 1.596;
offset = -222.92;
//orc_matrix2_u8 (dest, src1, src3, 75, 102, -14269 + 32, frame->width);
orc_matrix2_2_u8 (dest, src1, src3, 75, 102, 32, 6, frame->width);
/* m1 = 1.1644;
* m2 = 0;
* m3 = 1.596; */
orc_matrix2_u8 (dest, src1, src3, 75, 102, -14269 + 32, frame->width);
break;
case 1:
m1 = 1.1644;
m2 = -0.39176;
m3 = -0.81297;
offset = 135.58;
//orc_matrix3_u8 (dest, src1, src2, src3, 75, -25, -52, 8677 + 32,
// frame->width);
orc_matrix3_2_u8 (dest, src1, src2, src3, 75, -25, -52, 32, 6,
/* m1 = 1.1644;
* m2 = -0.39176;
* m3 = -0.81297; */
orc_matrix3_u8 (dest, src1, src2, src3, 75, -25, -52, 8677 + 32,
frame->width);
break;
case 2:
m1 = 1.1644;
m2 = 2.0172;
m3 = 0;
offset = -276.84;
//orc_matrix2_u8 (dest, src1, src2, 75, 129, -17718 + 32, frame->width);
orc_matrix2_2_u8 (dest, src1, src2, 75, 129, 32, 6, frame->width);
/* m1 = 1.1644;
* m2 = 2.0172;
* m3 = 0; */
orc_matrix2_u8 (dest, src1, src2, 75, 129, -17718 + 32, frame->width);
break;
default:
m1 = 0.0;
m2 = 0.0;
m3 = 0.0;
offset = 0;
break;
}
}
static void
color_matrix_YCbCr_to_RGB_8bit (CogFrame * frame, void *_dest, int component,
int i)
{
uint8_t *dest = _dest;
uint8_t *src1;
uint8_t *src2;
uint8_t *src3;
src1 = cog_virt_frame_get_line (frame->virt_frame1, 0, i);
src2 = cog_virt_frame_get_line (frame->virt_frame1, 1, i);
src3 = cog_virt_frame_get_line (frame->virt_frame1, 2, i);
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);
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);
break;
case 2:
/* m1 = 1.1644;
* m2 = 2.0172;
* m3 = 0; */
orc_matrix2_12_u8 (dest, src1, src2, 42, 4, 128, 8, frame->width);
break;
default:
break;
}
}
CogFrame *
cog_virt_frame_new_color_matrix_YCbCr_to_RGB (CogFrame * vf)
cog_virt_frame_new_color_matrix_YCbCr_to_RGB (CogFrame * vf, int bits)
{
CogFrame *virt_frame;
virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_U8_444,
vf->width, vf->height);
virt_frame->virt_frame1 = vf;
virt_frame->render_line = color_matrix_YCbCr_to_RGB;
if (bits <= 6) {
virt_frame->render_line = color_matrix_YCbCr_to_RGB_6bit;
} else {
virt_frame->render_line = color_matrix_YCbCr_to_RGB_8bit;
}
return virt_frame;
}

View file

@ -27,7 +27,7 @@ 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);
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_subsample (CogFrame *vf, CogFrameFormat format);

View file

@ -427,15 +427,18 @@ gst_cogcolorspace_transform (GstBaseTransform * base_transform,
}
frame = cog_virt_frame_new_unpack (frame);
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_subsample (frame, new_subsample);
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);
}
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_YCbCr_to_RGB (frame,
(compress->quality > 5) ? 8 : 6);
}
switch (out_format) {