diff --git a/ext/cog/cog.orc b/ext/cog/cog.orc index 1b2c5820ef..dabb192b3f 100644 --- a/ext/cog/cog.orc +++ b/ext/cog/cog.orc @@ -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 diff --git a/ext/cog/cogvirtframe.c b/ext/cog/cogvirtframe.c index 21d0e4c4a3..836b1af946 100644 --- a/ext/cog/cogvirtframe.c +++ b/ext/cog/cogvirtframe.c @@ -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; } diff --git a/ext/cog/cogvirtframe.h b/ext/cog/cogvirtframe.h index eca491446f..3895b4ea35 100644 --- a/ext/cog/cogvirtframe.h +++ b/ext/cog/cogvirtframe.h @@ -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); diff --git a/ext/cog/generate_tables.c b/ext/cog/generate_tables.c index a04946d9ea..224e5693ba 100644 --- a/ext/cog/generate_tables.c +++ b/ext/cog/generate_tables.c @@ -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; } diff --git a/ext/cog/gstcogcolorspace.c b/ext/cog/gstcogcolorspace.c index 1663a848fd..c076f5e0f2 100644 --- a/ext/cog/gstcogcolorspace.c +++ b/ext/cog/gstcogcolorspace.c @@ -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); diff --git a/ext/cog/gstlogoinsert.c b/ext/cog/gstlogoinsert.c index 9eb9141722..4aea9fa2e6 100644 --- a/ext/cog/gstlogoinsert.c +++ b/ext/cog/gstlogoinsert.c @@ -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); }