mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
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:
parent
26ab6d772a
commit
4ee3afc051
4 changed files with 157 additions and 66 deletions
|
@ -264,7 +264,7 @@ shrsw t1, t1, 6
|
||||||
convsuswb d1, t1
|
convsuswb d1, t1
|
||||||
|
|
||||||
|
|
||||||
.function orc_matrix2_2_u8
|
.function orc_matrix2_11_u8
|
||||||
.dest 1 d1 uint8_t
|
.dest 1 d1 uint8_t
|
||||||
.source 1 s1 uint8_t
|
.source 1 s1 uint8_t
|
||||||
.source 1 s2 uint8_t
|
.source 1 s2 uint8_t
|
||||||
|
@ -274,17 +274,49 @@ convsuswb d1, t1
|
||||||
.param 2 p4
|
.param 2 p4
|
||||||
.temp 2 t1
|
.temp 2 t1
|
||||||
.temp 2 t2
|
.temp 2 t2
|
||||||
|
.temp 2 t3
|
||||||
|
.temp 2 t4
|
||||||
|
|
||||||
convubw t1, s1
|
convubw t1, s1
|
||||||
subw t1, t1, 16
|
subw t1, t1, 16
|
||||||
mullw t1, t1, p1
|
mullw t3, t1, p1
|
||||||
convubw t2, s2
|
convubw t2, s2
|
||||||
subw t2, t2, 128
|
subw t2, t2, 128
|
||||||
mullw t2, t2, p2
|
mullw t4, t2, p2
|
||||||
addw t1, t1, t2
|
addw t3, t3, t4
|
||||||
addw t1, t1, p3
|
addw t3, t3, p3
|
||||||
shrsw t1, t1, p4
|
shrsw t3, t3, p4
|
||||||
convsuswb d1, t1
|
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
|
.function orc_matrix3_u8
|
||||||
|
@ -312,7 +344,7 @@ shrsw t1, t1, 6
|
||||||
convsuswb d1, t1
|
convsuswb d1, t1
|
||||||
|
|
||||||
|
|
||||||
.function orc_matrix3_2_u8
|
.function orc_matrix3_100_u8
|
||||||
.dest 1 d1 uint8_t
|
.dest 1 d1 uint8_t
|
||||||
.source 1 s1 uint8_t
|
.source 1 s1 uint8_t
|
||||||
.source 1 s2 uint8_t
|
.source 1 s2 uint8_t
|
||||||
|
@ -324,20 +356,53 @@ convsuswb d1, t1
|
||||||
.param 2 p5
|
.param 2 p5
|
||||||
.temp 2 t1
|
.temp 2 t1
|
||||||
.temp 2 t2
|
.temp 2 t2
|
||||||
|
.temp 2 t3
|
||||||
|
#.temp 2 t4
|
||||||
|
|
||||||
convubw t1, s1
|
convubw t1, s1
|
||||||
subw t1, t1, 16
|
subw t1, t1, 16
|
||||||
mullw t1, t1, p1
|
mullw t3, t1, p1
|
||||||
convubw t2, s2
|
convubw t2, s2
|
||||||
subw t2, t2, 128
|
subw t2, t2, 128
|
||||||
mullw t2, t2, p2
|
mullw t2, t2, p2
|
||||||
addw t1, t1, t2
|
addw t3, t3, t2
|
||||||
convubw t2, s3
|
convubw t2, s3
|
||||||
subw t2, t2, 128
|
subw t2, t2, 128
|
||||||
mullw t2, t2, p3
|
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, t2
|
||||||
addw t1, t1, p4
|
addw t1, t1, p4
|
||||||
shrsw t1, t1, p5
|
shrsw t1, t1, p5
|
||||||
|
addw t1, t1, p6
|
||||||
convsuswb d1, t1
|
convsuswb d1, t1
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1296,8 +1296,6 @@ 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;
|
||||||
double m1, m2, m3;
|
|
||||||
double offset;
|
|
||||||
|
|
||||||
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);
|
||||||
|
@ -1306,45 +1304,40 @@ 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;
|
/* m1 = 0.25679;
|
||||||
m2 = 0.50413;
|
* m2 = 0.50413;
|
||||||
m3 = 0.097906;
|
* m3 = 0.097906; */
|
||||||
offset = 16;
|
orc_matrix3_000_u8 (dest, src1, src2, src3,
|
||||||
orc_matrix3_u8 (dest, src1, src2, src3, 16, 32, 6, 16, frame->width);
|
66, 129, 25, 128, 8, 16, frame->width);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
m1 = -0.14822;
|
/* m1 = -0.14822;
|
||||||
m2 = -0.29099;
|
* m2 = -0.29099;
|
||||||
m3 = 0.43922;
|
* m3 = 0.43922; */
|
||||||
offset = 128;
|
orc_matrix3_000_u8 (dest, src1, src2, src3,
|
||||||
orc_matrix3_u8 (dest, src1, src2, src3, -9, -19, 28, 128, frame->width);
|
-37, -74, 112, 128, 8, 128, frame->width);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
m1 = 0.43922;
|
/* m1 = 0.43922;
|
||||||
m2 = -0.36779;
|
* m2 = -0.36779;
|
||||||
m3 = -0.071427;
|
* m3 = -0.071427; */
|
||||||
offset = 128;
|
orc_matrix3_000_u8 (dest, src1, src2, src3,
|
||||||
orc_matrix3_u8 (dest, src1, src2, src3, 28, -24, -5, 128, frame->width);
|
112, -94, 18, 128, 8, 128, frame->width);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
m1 = 0.0;
|
|
||||||
m2 = 0.0;
|
|
||||||
m3 = 0.0;
|
|
||||||
offset = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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 *dest = _dest;
|
||||||
uint8_t *src1;
|
uint8_t *src1;
|
||||||
uint8_t *src2;
|
uint8_t *src2;
|
||||||
uint8_t *src3;
|
uint8_t *src3;
|
||||||
double m1, m2, m3;
|
|
||||||
double offset;
|
|
||||||
|
|
||||||
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);
|
||||||
|
@ -1352,50 +1345,80 @@ color_matrix_YCbCr_to_RGB (CogFrame * frame, void *_dest, int component, int i)
|
||||||
|
|
||||||
switch (component) {
|
switch (component) {
|
||||||
case 0:
|
case 0:
|
||||||
m1 = 1.1644;
|
/* m1 = 1.1644;
|
||||||
m2 = 0;
|
* m2 = 0;
|
||||||
m3 = 1.596;
|
* m3 = 1.596; */
|
||||||
offset = -222.92;
|
orc_matrix2_u8 (dest, src1, src3, 75, 102, -14269 + 32, frame->width);
|
||||||
//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);
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
m1 = 1.1644;
|
/* m1 = 1.1644;
|
||||||
m2 = -0.39176;
|
* m2 = -0.39176;
|
||||||
m3 = -0.81297;
|
* m3 = -0.81297; */
|
||||||
offset = 135.58;
|
orc_matrix3_u8 (dest, src1, src2, src3, 75, -25, -52, 8677 + 32,
|
||||||
//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,
|
|
||||||
frame->width);
|
frame->width);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
m1 = 1.1644;
|
/* m1 = 1.1644;
|
||||||
m2 = 2.0172;
|
* m2 = 2.0172;
|
||||||
m3 = 0;
|
* m3 = 0; */
|
||||||
offset = -276.84;
|
orc_matrix2_u8 (dest, src1, src2, 75, 129, -17718 + 32, frame->width);
|
||||||
//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);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
m1 = 0.0;
|
|
||||||
m2 = 0.0;
|
|
||||||
m3 = 0.0;
|
|
||||||
offset = 0;
|
|
||||||
break;
|
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 *
|
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;
|
CogFrame *virt_frame;
|
||||||
|
|
||||||
virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_U8_444,
|
virt_frame = cog_frame_new_virtual (NULL, COG_FRAME_FORMAT_U8_444,
|
||||||
vf->width, vf->height);
|
vf->width, vf->height);
|
||||||
virt_frame->virt_frame1 = vf;
|
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;
|
return virt_frame;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_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);
|
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_RGB_to_YCbCr (CogFrame * vf);
|
||||||
CogFrame *cog_virt_frame_new_subsample (CogFrame *vf, CogFrameFormat format);
|
CogFrame *cog_virt_frame_new_subsample (CogFrame *vf, CogFrameFormat format);
|
||||||
|
|
||||||
|
|
|
@ -427,15 +427,18 @@ gst_cogcolorspace_transform (GstBaseTransform * base_transform,
|
||||||
}
|
}
|
||||||
|
|
||||||
frame = cog_virt_frame_new_unpack (frame);
|
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);
|
frame = cog_virt_frame_new_subsample (frame, new_subsample);
|
||||||
|
|
||||||
if (gst_video_format_is_rgb (out_format) &&
|
if (gst_video_format_is_rgb (out_format) &&
|
||||||
gst_video_format_is_yuv (in_format)) {
|
gst_video_format_is_yuv (in_format)) {
|
||||||
frame = cog_virt_frame_new_color_matrix_YCbCr_to_RGB (frame);
|
frame = cog_virt_frame_new_color_matrix_YCbCr_to_RGB (frame,
|
||||||
}
|
(compress->quality > 5) ? 8 : 6);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (out_format) {
|
switch (out_format) {
|
||||||
|
|
Loading…
Reference in a new issue