From 994156c1b8779ea879591eb32def0dc0e6a41b7a Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Mon, 3 Jan 2011 20:05:52 +0100 Subject: [PATCH] dvbsuboverlay: remove unnecessary RGB -> YUV conversion by using YUV palettes the default CLUTs still use RGB -> YUV conversions since the standard defines them as RGBA values. --- gst/dvbsuboverlay/dvb-sub.c | 86 +++++++++++++----------- gst/dvbsuboverlay/gstdvbsuboverlay.c | 126 ++++++++--------------------------- 2 files changed, 75 insertions(+), 137 deletions(-) diff --git a/gst/dvbsuboverlay/dvb-sub.c b/gst/dvbsuboverlay/dvb-sub.c index 2593622..eb68106 100644 --- a/gst/dvbsuboverlay/dvb-sub.c +++ b/gst/dvbsuboverlay/dvb-sub.c @@ -33,7 +33,6 @@ #include /* memset */ #include /* GST_READ_UINT16_BE */ #include /* GstBitReader */ -#include "ffmpeg-colorspace.h" /* YUV_TO_RGB1_CCIR */ /* FIXME: Just give YUV data to gstreamer then? */ #include "dvb-sub.h" @@ -55,13 +54,10 @@ static void dvb_sub_init (void); */ #define MAX_NEG_CROP 1024 -static guint8 ff_cropTbl[256 + 2 * MAX_NEG_CROP] = { 0, }; -#define cm (ff_cropTbl + MAX_NEG_CROP) +#define AYUV(y,u,v,a) (((a) << 24) | ((y) << 16) | ((u) << 8) | (v)) +#define RGBA_TO_AYUV(r,g,b,a) (((a) << 24) | ((rgb_to_y(r,g,b)) << 16) | ((rgb_to_u(r,g,b)) << 8) | (rgb_to_v(r,g,b))) -/* FIXME: This is really ARGB... We might need this configurable for performant - * FIXME: use in GStreamer as well if that likes RGBA more (Qt prefers ARGB) */ -#define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) typedef struct DVBSubCLUT { @@ -156,6 +152,40 @@ typedef enum BOTTOM_FIELD = 1 } DvbSubPixelDataSubBlockFieldType; +static inline gint +rgb_to_y (gint r, gint g, gint b) +{ + gint ret; + + ret = (gint) (((19595 * r) >> 16) + ((38470 * g) >> 16) + ((7471 * b) >> 16)); + ret = CLAMP (ret, 0, 255); + return ret; +} + +static inline gint +rgb_to_u (gint r, gint g, gint b) +{ + gint ret; + + ret = + (gint) (-((11059 * r) >> 16) - ((21709 * g) >> 16) + ((32768 * b) >> 16) + + 128); + ret = CLAMP (ret, 0, 255); + return ret; +} + +static inline gint +rgb_to_v (gint r, gint g, gint b) +{ + gint ret; + + ret = + (gint) (((32768 * r) >> 16) - ((27439 * g) >> 16) - ((5329 * b) >> 16) + + 128); + ret = CLAMP (ret, 0, 255); + return ret; +} + static DVBSubObject * get_object (DvbSub * dvb_sub, guint16 object_id) { @@ -263,20 +293,6 @@ delete_state (DvbSub * dvb_sub) g_warn_if_fail (dvb_sub->object_list == NULL); } -/* init static data necessary for ffmpeg-colorspace conversion */ -static void -dsputil_static_init (void) -{ - int i; - - for (i = 0; i < 256; i++) - ff_cropTbl[i + MAX_NEG_CROP] = i; - for (i = 0; i < MAX_NEG_CROP; i++) { - ff_cropTbl[i] = 0; - ff_cropTbl[i + MAX_NEG_CROP + 256] = 255; - } -} - static void dvb_sub_init (void) { @@ -284,19 +300,17 @@ dvb_sub_init (void) GST_DEBUG_CATEGORY_INIT (dvbsub_debug, "dvbsub", 0, "dvbsuboverlay parser"); - dsputil_static_init (); /* Initializes ff_cropTbl table, used in YUV_TO_RGB conversion */ - /* Initialize the static default_clut structure, from which other clut * structures are initialized from (to start off with default CLUTs * as defined in the specification). */ default_clut.id = -1; - default_clut.clut4[0] = RGBA (0, 0, 0, 0); - default_clut.clut4[1] = RGBA (255, 255, 255, 255); - default_clut.clut4[2] = RGBA (0, 0, 0, 255); - default_clut.clut4[3] = RGBA (127, 127, 127, 255); + default_clut.clut4[0] = RGBA_TO_AYUV (0, 0, 0, 0); + default_clut.clut4[1] = RGBA_TO_AYUV (255, 255, 255, 255); + default_clut.clut4[2] = RGBA_TO_AYUV (0, 0, 0, 255); + default_clut.clut4[3] = RGBA_TO_AYUV (127, 127, 127, 255); - default_clut.clut16[0] = RGBA (0, 0, 0, 0); + default_clut.clut16[0] = RGBA_TO_AYUV (0, 0, 0, 0); for (i = 1; i < 16; i++) { if (i < 8) { r = (i & 1) ? 255 : 0; @@ -307,10 +321,10 @@ dvb_sub_init (void) g = (i & 2) ? 127 : 0; b = (i & 4) ? 127 : 0; } - default_clut.clut16[i] = RGBA (r, g, b, 255); + default_clut.clut16[i] = RGBA_TO_AYUV (r, g, b, 255); } - default_clut.clut256[0] = RGBA (0, 0, 0, 0); + default_clut.clut256[0] = RGBA_TO_AYUV (0, 0, 0, 0); for (i = 1; i < 256; i++) { if (i < 8) { r = (i & 1) ? 255 : 0; @@ -345,7 +359,7 @@ dvb_sub_init (void) break; } } - default_clut.clut256[i] = RGBA (r, g, b, a); + default_clut.clut256[i] = RGBA_TO_AYUV (r, g, b, a); } } @@ -564,7 +578,6 @@ _dvb_sub_parse_clut_segment (DvbSub * dvb_sub, guint16 page_id, guint8 * buf, DVBSubCLUT *clut; int entry_id, depth, full_range; int y, cr, cb, alpha; - int r, g, b, r_add, g_add, b_add; GST_MEMDUMP ("DVB clut packet", buf, buf_size); @@ -613,18 +626,15 @@ _dvb_sub_parse_clut_segment (DvbSub * dvb_sub, guint16 page_id, guint8 * buf, if (y == 0) alpha = 0xff; - YUV_TO_RGB1_CCIR (cb, cr); - YUV_TO_RGB2_CCIR (r, g, b, y); - - GST_DEBUG ("CLUT DEFINITION: clut %d := (%d,%d,%d,%d)", entry_id, r, g, b, + GST_DEBUG ("CLUT DEFINITION: clut %d := (%d,%d,%d,%d)", entry_id, y, cb, cr, alpha); if (depth & 0x80) - clut->clut4[entry_id] = RGBA (r, g, b, 255 - alpha); + clut->clut4[entry_id] = AYUV (y, cb, cr, 255 - alpha); if (depth & 0x40) - clut->clut16[entry_id] = RGBA (r, g, b, 255 - alpha); + clut->clut16[entry_id] = AYUV (y, cb, cr, 255 - alpha); if (depth & 0x20) - clut->clut256[entry_id] = RGBA (r, g, b, 255 - alpha); + clut->clut256[entry_id] = AYUV (y, cb, cr, 255 - alpha); } } diff --git a/gst/dvbsuboverlay/gstdvbsuboverlay.c b/gst/dvbsuboverlay/gstdvbsuboverlay.c index 64cfe9c..ca6789a 100644 --- a/gst/dvbsuboverlay/gstdvbsuboverlay.c +++ b/gst/dvbsuboverlay/gstdvbsuboverlay.c @@ -423,47 +423,11 @@ gst_dvbsub_overlay_getcaps (GstPad * pad) return caps; } -static inline gint -rgb_to_y (gint r, gint g, gint b) -{ - gint ret; - - ret = (gint) (((19595 * r) >> 16) + ((38470 * g) >> 16) + ((7471 * b) >> 16)); - ret = CLAMP (ret, 0, 255); - return ret; -} - -static inline gint -rgb_to_u (gint r, gint g, gint b) -{ - gint ret; - - ret = - (gint) (-((11059 * r) >> 16) - ((21709 * g) >> 16) + ((32768 * b) >> 16) + - 128); - ret = CLAMP (ret, 0, 255); - return ret; -} - -static inline gint -rgb_to_v (gint r, gint g, gint b) -{ - gint ret; - - ret = - (gint) (((32768 * r) >> 16) - ((27439 * g) >> 16) - ((5329 * b) >> 16) + - 128); - ret = CLAMP (ret, 0, 255); - return ret; -} - -/* FIXME: DVB-SUB actually provides us AYUV from CLUT, but libdvbsub used to convert it to ARGB */ static void blit_i420 (GstDVBSubOverlay * overlay, DVBSubtitles * subs, GstBuffer * buffer) { guint counter; DVBSubtitleRect *sub_region; - gint r, g, b; gint a1, a2, a3, a4; gint y1, y2, y3, y4; gint u1, u2, u3, u4; @@ -574,49 +538,33 @@ blit_i420 (GstDVBSubOverlay * overlay, DVBSubtitles * subs, GstBuffer * buffer) color = sub_region->pict.palette[src[(sy >> 16) * src_stride + (sx >> 16)]]; a1 = (color >> 24) & 0xff; - r = (color >> 16) & 0xff; - g = (color >> 8) & 0xff; - b = color & 0xff; - - y1 = rgb_to_y (r, g, b); - u1 = rgb_to_u (r, g, b); - v1 = rgb_to_v (r, g, b); + y1 = (color >> 16) & 0xff; + u1 = (color >> 8) & 0xff; + v1 = color & 0xff; color = sub_region->pict.palette[src[(sy >> 16) * src_stride + ((sx + xstep) >> 16)]]; a2 = (color >> 24) & 0xff; - r = (color >> 16) & 0xff; - g = (color >> 8) & 0xff; - b = color & 0xff; - - y2 = rgb_to_y (r, g, b); - u2 = rgb_to_u (r, g, b); - v2 = rgb_to_v (r, g, b); + y2 = (color >> 16) & 0xff; + u2 = (color >> 8) & 0xff; + v2 = color & 0xff; color = sub_region->pict.palette[src[((sy + ystep) >> 16) * src_stride + (sx >> 16)]]; a3 = (color >> 24) & 0xff; - r = (color >> 16) & 0xff; - g = (color >> 8) & 0xff; - b = color & 0xff; - - y3 = rgb_to_y (r, g, b); - u3 = rgb_to_u (r, g, b); - v3 = rgb_to_v (r, g, b); + y3 = (color >> 16) & 0xff; + u3 = (color >> 8) & 0xff; + v3 = color & 0xff; color = sub_region->pict.palette[src[((sy + ystep) >> 16) * src_stride + ((sx + xstep) >> 16)]]; a4 = (color >> 24) & 0xff; - r = (color >> 16) & 0xff; - g = (color >> 8) & 0xff; - b = color & 0xff; - - y4 = rgb_to_y (r, g, b); - u4 = rgb_to_u (r, g, b); - v4 = rgb_to_v (r, g, b); + y4 = (color >> 16) & 0xff; + u4 = (color >> 8) & 0xff; + v4 = color & 0xff; dst_y[0] = (a1 * y1 + (255 - a1) * dst_y[0]) / 255; dst_y[1] = (a2 * y2 + (255 - a2) * dst_y[1]) / 255; @@ -641,25 +589,17 @@ blit_i420 (GstDVBSubOverlay * overlay, DVBSubtitles * subs, GstBuffer * buffer) color = sub_region->pict.palette[src[(sy >> 16) * src_stride + (sx >> 16)]]; a1 = (color >> 24) & 0xff; - r = (color >> 16) & 0xff; - g = (color >> 8) & 0xff; - b = color & 0xff; - - y1 = rgb_to_y (r, g, b); - u1 = rgb_to_u (r, g, b); - v1 = rgb_to_v (r, g, b); + y1 = (color >> 16) & 0xff; + u1 = (color >> 8) & 0xff; + v1 = color & 0xff; color = sub_region->pict.palette[src[((sy + ystep) >> 16) * src_stride + (sx >> 16)]]; a3 = (color >> 24) & 0xff; - r = (color >> 16) & 0xff; - g = (color >> 8) & 0xff; - b = color & 0xff; - - y3 = rgb_to_y (r, g, b); - u3 = rgb_to_u (r, g, b); - v3 = rgb_to_v (r, g, b); + y3 = (color >> 16) & 0xff; + u3 = (color >> 8) & 0xff; + v3 = color & 0xff; dst_y[0] = (a1 * y1 + (255 - a1) * dst_y[0]) / 255; dst_y2[0] = (a3 * y3 + (255 - a3) * dst_y2[0]) / 255; @@ -690,25 +630,17 @@ blit_i420 (GstDVBSubOverlay * overlay, DVBSubtitles * subs, GstBuffer * buffer) color = sub_region->pict.palette[src[(sy >> 16) * src_stride + (sx >> 16)]]; a1 = (color >> 24) & 0xff; - r = (color >> 16) & 0xff; - g = (color >> 8) & 0xff; - b = color & 0xff; - - y1 = rgb_to_y (r, g, b); - u1 = rgb_to_u (r, g, b); - v1 = rgb_to_v (r, g, b); + y1 = (color >> 16) & 0xff; + u1 = (color >> 8) & 0xff; + v1 = color & 0xff; color = sub_region->pict.palette[src[(sy >> 16) * src_stride + ((sx + xstep) >> 16)]]; a2 = (color >> 24) & 0xff; - r = (color >> 16) & 0xff; - g = (color >> 8) & 0xff; - b = color & 0xff; - - y2 = rgb_to_y (r, g, b); - u2 = rgb_to_u (r, g, b); - v2 = rgb_to_v (r, g, b); + y2 = (color >> 16) & 0xff; + u2 = (color >> 8) & 0xff; + v2 = color & 0xff; dst_y[0] = (a1 * y1 + (255 - a1) * dst_y[0]) / 255; dst_y[1] = (a2 * y2 + (255 - a2) * dst_y[1]) / 255; @@ -728,13 +660,9 @@ blit_i420 (GstDVBSubOverlay * overlay, DVBSubtitles * subs, GstBuffer * buffer) color = sub_region->pict.palette[src[(sy >> 16) * src_stride + (sx >> 16)]]; a1 = (color >> 24) & 0xff; - r = (color >> 16) & 0xff; - g = (color >> 8) & 0xff; - b = color & 0xff; - - y1 = rgb_to_y (r, g, b); - u1 = rgb_to_u (r, g, b); - v1 = rgb_to_v (r, g, b); + y1 = (color >> 16) & 0xff; + u1 = (color >> 8) & 0xff; + v1 = color & 0xff; dst_y[0] = (a1 * y1 + (255 - a1) * dst_y[0]) / 255; -- 2.7.4