From e3b6a1f138c83633fb9885c793ead4bf6093beab Mon Sep 17 00:00:00 2001 From: Torsten Jager Date: Fri, 30 May 2014 15:05:50 +0200 Subject: Add yuv overlay color matrix support. "Never assume an API to be stable unless at least 1 month has passed after adding." --- src/video_out/video_out_opengl2.c | 2 +- src/video_out/video_out_raw.c | 2 +- src/video_out/video_out_vaapi.c | 2 +- src/xine-engine/alphablend.c | 107 ++++++++++++++++++++++++++++---------- src/xine-engine/video_overlay.c | 6 +-- 5 files changed, 86 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/video_out/video_out_opengl2.c b/src/video_out/video_out_opengl2.c index 45c5abf16..c2f7b2012 100644 --- a/src/video_out/video_out_opengl2.c +++ b/src/video_out/video_out_opengl2.c @@ -612,7 +612,7 @@ static void opengl2_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, if (overlay->rle) { if (!overlay->rgb_clut || !overlay->hili_rgb_clut) { - _x_overlay_clut_yuv2rgb(overlay); + _x_overlay_clut_yuv2rgb(overlay, this->color_standard); } } diff --git a/src/video_out/video_out_raw.c b/src/video_out/video_out_raw.c index a19285707..eee6e6ff4 100644 --- a/src/video_out/video_out_raw.c +++ b/src/video_out/video_out_raw.c @@ -140,7 +140,7 @@ static void raw_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_ if (overlay->rle) { if (!overlay->rgb_clut || !overlay->hili_rgb_clut) - _x_overlay_clut_yuv2rgb (overlay); + _x_overlay_clut_yuv2rgb (overlay, 0); if ( raw_process_ovl( this, overlay ) ) ++this->ovl_changed; } diff --git a/src/video_out/video_out_vaapi.c b/src/video_out/video_out_vaapi.c index 823d0fc5a..d4e7d5928 100644 --- a/src/video_out/video_out_vaapi.c +++ b/src/video_out/video_out_vaapi.c @@ -2723,7 +2723,7 @@ static void vaapi_overlay_end (vo_driver_t *this_gen, vo_frame_t *frame_gen) { continue; if (!ovl->rgb_clut || !ovl->hili_rgb_clut) - _x_overlay_clut_yuv2rgb (ovl); + _x_overlay_clut_yuv2rgb (ovl, this->color_matrix); bitmap = malloc(ovl->width * ovl->height * sizeof(uint32_t)); diff --git a/src/xine-engine/alphablend.c b/src/xine-engine/alphablend.c index e83061c50..f876545e9 100644 --- a/src/xine-engine/alphablend.c +++ b/src/xine-engine/alphablend.c @@ -2185,36 +2185,89 @@ void _x_alphablend_free(alphablend_t *extra_data) #define saturate(v) if (v & ~255) v = (~((uint32_t)v)) >> 24 -void _x_clut_yuv2rgb(uint32_t *clut, int num_items) +void _x_clut_yuv2rgb(uint32_t *clut, int num_items, int color_matrix) { uint32_t *end = clut + num_items; if (end <= clut) return; - while (clut < end) { - union { - uint32_t u32; - clut_t c; - } tmp = { *clut }; - - int32_t y, u, v, r, g, b; - - y = tmp.c.y; - u = tmp.c.cb; - v = tmp.c.cr; - - /* This is the middle between ITU 601 (SD) and 709 (HD), mpeg range. */ - y *= 76304; - r = (y + 111028 * v - 15432448) >> 16; - saturate (r); - g = (y - 19818 * u - 44093 * v + 6959744) >> 16; - saturate (g); - b = (y + 135306 * u - 18540032) >> 16; - saturate (b); - - /* see clut_to_argb () */ - tmp.c.cb = b; - tmp.c.cr = g; - tmp.c.y = r; - *clut++ = tmp.u32; + switch (color_matrix >> 1) { + + case 8: + while (clut < end) { + union { + uint32_t u32; + clut_t c; + } tmp = { *clut }; + int32_t y, u, v, r, g, b; + y = tmp.c.y; + u = tmp.c.cb; + v = tmp.c.cr; + /* Green Orange -- does this ever happen? */ + r = y - u + v; + saturate (r); + g = y + u - 128; + saturate (g); + b = y - u - v + 256; + saturate (b); + /* see clut_to_argb () */ + tmp.c.cb = b; + tmp.c.cr = g; + tmp.c.y = r; + *clut++ = tmp.u32; + } + break; + + case 1: + case 7: + while (clut < end) { + union { + uint32_t u32; + clut_t c; + } tmp = { *clut }; + int32_t y, u, v, r, g, b; + y = tmp.c.y; + u = tmp.c.cb; + v = tmp.c.cr; + /* ITU 709 (HD), mpeg range. */ + y *= 76304; + r = (y + 117473 * v - 16224640) >> 16; + saturate (r); + g = (y - 13972 * u - 34918 * v + 5069824) >> 16; + saturate (g); + b = (y + 138425 * u - 18906496) >> 16; + saturate (b); + /* see clut_to_argb () */ + tmp.c.cb = b; + tmp.c.cr = g; + tmp.c.y = r; + *clut++ = tmp.u32; + } + break; + + default: + while (clut < end) { + union { + uint32_t u32; + clut_t c; + } tmp = { *clut }; + int32_t y, u, v, r, g, b; + y = tmp.c.y; + u = tmp.c.cb; + v = tmp.c.cr; + /* ITU 601 (SD), mpeg range. */ + y *= 76304; + r = (y + 104582 * v - 14574592) >> 16; + saturate (r); + g = (y - 25664 * u - 53268 * v + 8849664) >> 16; + saturate (g); + b = (y + 132186 * u - 18107904) >> 16; + saturate (b); + /* see clut_to_argb () */ + tmp.c.cb = b; + tmp.c.cr = g; + tmp.c.y = r; + *clut++ = tmp.u32; + } + break; } } diff --git a/src/xine-engine/video_overlay.c b/src/xine-engine/video_overlay.c index e044d9d90..b250f6811 100644 --- a/src/xine-engine/video_overlay.c +++ b/src/xine-engine/video_overlay.c @@ -494,15 +494,15 @@ static int video_overlay_event( video_overlay_t *this, int64_t vpts ) { return processed; } -void _x_overlay_clut_yuv2rgb(vo_overlay_t *overlay) +void _x_overlay_clut_yuv2rgb(vo_overlay_t *overlay, int color_matrix) { if (!overlay->rgb_clut) { - _x_clut_yuv2rgb(overlay->color, sizeof(overlay->color) / sizeof (overlay->color[0])); + _x_clut_yuv2rgb(overlay->color, sizeof(overlay->color) / sizeof (overlay->color[0]), color_matrix); overlay->rgb_clut++; } if (!overlay->hili_rgb_clut) { - _x_clut_yuv2rgb(overlay->hili_color, sizeof (overlay->color) / sizeof (overlay->color[0])); + _x_clut_yuv2rgb(overlay->hili_color, sizeof (overlay->color) / sizeof (overlay->color[0]), color_matrix); overlay->hili_rgb_clut++; } } -- cgit v1.2.3