textoverlay: Add support for AYUV
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Wed, 1 Sep 2010 15:52:31 +0000 (17:52 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Wed, 1 Sep 2010 15:52:31 +0000 (17:52 +0200)
ext/pango/gsttextoverlay.c

index aa492e9..0dd8a10 100644 (file)
@@ -186,7 +186,8 @@ static GstStaticPadTemplate src_template_factory =
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";"
-        GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_YUV ("{I420, UYVY, NV12, NV21}"))
+        GST_VIDEO_CAPS_xRGB ";"
+        GST_VIDEO_CAPS_YUV ("{AYUV, I420, UYVY, NV12, NV21}"))
     );
 
 static GstStaticPadTemplate video_sink_template_factory =
@@ -194,7 +195,8 @@ static GstStaticPadTemplate video_sink_template_factory =
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";"
-        GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_YUV ("{I420, UYVY, NV12, NV21}"))
+        GST_VIDEO_CAPS_xRGB ";"
+        GST_VIDEO_CAPS_YUV ("{AYUV, I420, UYVY, NV12, NV21}"))
     );
 
 static GstStaticPadTemplate text_sink_template_factory =
@@ -1360,7 +1362,7 @@ gst_text_overlay_render_pangocairo (GstTextOverlay * overlay,
 #define BOX_YPAD         6
 
 static inline void
-gst_text_overlay_shade_Y (GstTextOverlay * overlay, guchar * dest,
+gst_text_overlay_shade_planar_Y (GstTextOverlay * overlay, guchar * dest,
     gint x0, gint x1, gint y0, gint y1)
 {
   gint i, j, dest_stride;
@@ -1384,12 +1386,18 @@ gst_text_overlay_shade_Y (GstTextOverlay * overlay, guchar * dest,
 }
 
 static inline void
-gst_text_overlay_shade_UYVY_y (GstTextOverlay * overlay, guchar * dest,
+gst_text_overlay_shade_packed_Y (GstTextOverlay * overlay, guchar * dest,
     gint x0, gint x1, gint y0, gint y1)
 {
   gint i, j;
-  guint dest_stride = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_UYVY, 0,
+  guint dest_stride, pixel_stride, component_offset;
+
+  dest_stride = gst_video_format_get_row_stride (overlay->format, 0,
       overlay->width);
+  pixel_stride = gst_video_format_get_pixel_stride (overlay->format, 0);
+  component_offset =
+      gst_video_format_get_component_offset (overlay->format, 0, overlay->width,
+      overlay->height);
 
   x0 = CLAMP (x0 - BOX_XPAD, 0, overlay->width);
   x1 = CLAMP (x1 + BOX_XPAD, 0, overlay->width);
@@ -1397,12 +1405,22 @@ gst_text_overlay_shade_UYVY_y (GstTextOverlay * overlay, guchar * dest,
   y0 = CLAMP (y0 - BOX_YPAD, 0, overlay->height);
   y1 = CLAMP (y1 + BOX_YPAD, 0, overlay->height);
 
+  if (x0 != 0)
+    x0 = gst_video_format_get_component_width (overlay->format, 0, x0);
+  if (x1 != 0)
+    x1 = gst_video_format_get_component_width (overlay->format, 0, x1);
+
+  if (y0 != 0)
+    y0 = gst_video_format_get_component_height (overlay->format, 0, y0);
+  if (y1 != 0)
+    y1 = gst_video_format_get_component_height (overlay->format, 0, y1);
+
   for (i = y0; i < y1; i++) {
     for (j = x0; j < x1; j++) {
       gint y;
       gint y_pos;
 
-      y_pos = (i * dest_stride) + j * 2 + 1;
+      y_pos = (i * dest_stride) + j * pixel_stride + component_offset;
       y = dest[y_pos] + overlay->shading_value;
 
       dest[y_pos] = CLAMP (y, 0, 255);
@@ -1585,6 +1603,57 @@ gst_text_overlay_blit_UYVY (GstTextOverlay * overlay,
   }
 }
 
+static inline void
+gst_text_overlay_blit_AYUV (GstTextOverlay * overlay,
+    guint8 * rgb_pixels, gint xpos, gint ypos)
+{
+  int a, r, g, b;
+  int y, u, v;
+  int i, j;
+  int h, w;
+  guchar *pimage, *dest;
+
+  w = overlay->image_width;
+  h = overlay->image_height;
+
+  if (xpos < 0) {
+    xpos = 0;
+  }
+
+  if (xpos + w > overlay->width) {
+    w = overlay->width - xpos;
+  }
+
+  if (ypos + h > overlay->height) {
+    h = overlay->height - ypos;
+  }
+
+  for (i = 0; i < h; i++) {
+    pimage = overlay->text_image + i * overlay->image_width * 4;
+    dest = rgb_pixels + (i + ypos) * 4 * overlay->width + xpos * 4;
+    for (j = 0; j < w; j++) {
+      a = pimage[CAIRO_ARGB_A];
+      b = pimage[CAIRO_ARGB_B];
+      g = pimage[CAIRO_ARGB_G];
+      r = pimage[CAIRO_ARGB_R];
+
+      CAIRO_UNPREMULTIPLY (a, r, g, b);
+
+      COMP_Y (y, r, g, b);
+      COMP_U (u, r, g, b);
+      COMP_V (v, r, g, b);
+
+      a = (a * dest[0] + 128) >> 8;
+      BLEND (dest[1], a, y, dest[1]);
+      BLEND (dest[2], a, u, dest[2]);
+      BLEND (dest[3], a, v, dest[3]);
+
+      pimage += 4;
+      dest += 4;
+    }
+  }
+}
+
 #define xRGB_BLIT_FUNCTION(name, R, G, B) \
 static inline void \
 gst_text_overlay_blit_##name (GstTextOverlay * overlay, \
@@ -1738,12 +1807,13 @@ gst_text_overlay_push_frame (GstTextOverlay * overlay, GstBuffer * video_frame)
       case GST_VIDEO_FORMAT_I420:
       case GST_VIDEO_FORMAT_NV12:
       case GST_VIDEO_FORMAT_NV21:
-        gst_text_overlay_shade_Y (overlay,
+        gst_text_overlay_shade_planar_Y (overlay,
             GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
             ypos, ypos + overlay->image_height);
         break;
+      case GST_VIDEO_FORMAT_AYUV:
       case GST_VIDEO_FORMAT_UYVY:
-        gst_text_overlay_shade_UYVY_y (overlay,
+        gst_text_overlay_shade_packed_Y (overlay,
             GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
             ypos, ypos + overlay->image_height);
         break;
@@ -1780,6 +1850,10 @@ gst_text_overlay_push_frame (GstTextOverlay * overlay, GstBuffer * video_frame)
         gst_text_overlay_blit_UYVY (overlay,
             GST_BUFFER_DATA (video_frame), xpos, ypos);
         break;
+      case GST_VIDEO_FORMAT_AYUV:
+        gst_text_overlay_blit_AYUV (overlay,
+            GST_BUFFER_DATA (video_frame), xpos, ypos);
+        break;
       case GST_VIDEO_FORMAT_BGRx:
         gst_text_overlay_blit_BGRx (overlay,
             GST_BUFFER_DATA (video_frame), xpos, ypos);