dvbsuboverlay: remove unnecessary RGB -> YUV conversion by using YUV palettes
authorJanne Grunau <janne.grunau@collabora.co.uk>
Mon, 3 Jan 2011 19:05:52 +0000 (20:05 +0100)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Mon, 3 Jan 2011 20:23:24 +0000 (20:23 +0000)
the default CLUTs still use RGB -> YUV conversions since the standard defines
them as RGBA values.

gst/dvbsuboverlay/dvb-sub.c
gst/dvbsuboverlay/gstdvbsuboverlay.c

index 2593622..eb68106 100644 (file)
@@ -33,7 +33,6 @@
 #include <string.h>             /* memset */
 #include <gst/gstutils.h>       /* GST_READ_UINT16_BE */
 #include <gst/base/gstbitreader.h>      /* 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);
   }
 }
 
index 64cfe9c..ca6789a 100644 (file)
@@ -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;