From 9a74d75ff7a89f761f7926aecea8cab502773e0c Mon Sep 17 00:00:00 2001 From: Torsten Jager Date: Tue, 10 Dec 2013 15:25:15 +0100 Subject: YCgCo: general preparation. I stumbled upon something - the green orange transform :-) No, it is not lossless as some publications say. Instead, like traditional YCbCr it maps the RGB color cube to a pyramid with a central symmetric hexagonal base. Roughly 80% of color depth gets lost this way. The green resolution is again worse than ITU-R 709. It will probably not replace traditional YCbCr. It is incompatible with existing video equipment, and it lacks an mpeg range mode needed for live editing. However, if you can live without video equalizer, it makes an interesting alternative for slow devices like smartphones. Anyway, just if someone likes... --- src/video_out/color_matrix.c | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/video_out/color_matrix.c b/src/video_out/color_matrix.c index 32fe3f61c..22dad1dc5 100644 --- a/src/video_out/color_matrix.c +++ b/src/video_out/color_matrix.c @@ -26,6 +26,7 @@ This file must be included after declaration of xxxx_driver_t, and #define'ing CM_DRIVER_T to it. That struct must contain the integer value cm_state. + Also #define CM_HAVE_YCGCO_SUPPORT if you already handle that. cm_from_frame () returns current (color_matrix << 1) | color_range control value. Having only 1 var simplifies change event handling and avoids unecessary vo @@ -52,9 +53,8 @@ So I decided to provide functionality, and let the user decide if and how to actually use it. - BTW. VDPAU already has its own matrix switch based on stream info. - Rumour has it that proprietory ATI drivers auto switch their xv ports - based on video size. Both not user configurable, and both not tested... + BTW. Rumour has it that proprietory ATI drivers auto switch their xv ports + based on video size. not user configurable, and not tested... */ /* eveybody gets these */ @@ -88,6 +88,25 @@ static const char * const cm_names[] = { "full range SMPTE 170M", "SMPTE 240M", "full range SMPTE 240M" +#ifdef CM_HAVE_YCGCO_SUPPORT + , + "YCgCo", + "YCgCo", /* this is always fullrange */ + "#9", + "fullrange #9", + "#10", + "fullrange #10", + "#11", + "fullrange #11", + "#12", + "fullrange #12", + "#13", + "fullrange #13", + "#14", + "fullrange #14", + "#15", + "fullrange #15" +#endif }; #ifdef CM_DRIVER_T @@ -153,10 +172,10 @@ static void cm_init (CM_DRIVER_T *this) { } static uint8_t cm_m[] = { - 5, 1, 5, 3, 4, 5, 6, 7, /* SIGNAL */ - 5, 1, 5, 3, 4, 5, 6, 7, /* SIZE */ - 5, 5, 5, 5, 5, 5, 5, 5, /* SD */ - 5, 1, 1, 1, 1, 1, 1, 1 /* HD */ + 5, 1, 5, 3, 4, 5, 6, 7, 8, 5, 5, 5, 5, 5, 5, 5, /* SIGNAL */ + 5, 1, 5, 3, 4, 5, 6, 7, 8, 5, 5, 5, 5, 5, 5, 5, /* SIZE */ + 5, 5, 5, 5, 5, 5, 5, 5, 8, 5, 5, 5, 5, 5, 5, 5, /* SD */ + 5, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1 /* HD */ }; static uint8_t cm_r[] = {0, 0, 1, 0}; /* AUTO, MPEG, FULL, safety */ @@ -166,10 +185,14 @@ static int cm_from_frame (vo_frame_t *frame) { int cm = VO_GET_FLAGS_CM (frame->flags); int cf = this->cm_state; - cm_m[10] = (frame->height - frame->crop_top - frame->crop_bottom >= 720) || + cm_m[18] = (frame->height - frame->crop_top - frame->crop_bottom >= 720) || (frame->width - frame->crop_left - frame->crop_right >= 1280) ? 1 : 5; cm_r[0] = cm & 1; - return ((cm_m[((cf >> 2) << 3) | (cm >> 1)] << 1) | cm_r[cf & 2]); +#ifdef CM_HAVE_YCGCO_SUPPORT + return ((cm_m[((cf >> 2) << 4) | (cm >> 1)] << 1) | cm_r[cf & 2]); +#else + return ((cm_m[((cf >> 2) << 4) | (cm >> 1)] << 1) | cm_r[cf & 2]) & 15; +#endif } static void cm_close (CM_DRIVER_T *this) { -- cgit v1.2.3