From 200ee96338e73932074ad977d2187a7b7c163d96 Mon Sep 17 00:00:00 2001 From: Lane Brooks Date: Mon, 17 Jan 2011 21:12:18 -0700 Subject: [PATCH] textoverlay: Added support for ARGB and other RGB alpha variants --- ext/pango/gsttextoverlay.c | 123 +++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c index 6cd9db7afe..1d0f25b849 100644 --- a/ext/pango/gsttextoverlay.c +++ b/ext/pango/gsttextoverlay.c @@ -193,6 +193,10 @@ static GstStaticPadTemplate src_template_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_xRGB ";" + GST_VIDEO_CAPS_RGBA ";" + GST_VIDEO_CAPS_BGRA ";" + GST_VIDEO_CAPS_ARGB ";" + GST_VIDEO_CAPS_ABGR ";" GST_VIDEO_CAPS_YUV ("{AYUV, I420, UYVY, NV12, NV21}")) ); @@ -202,6 +206,10 @@ static GstStaticPadTemplate video_sink_template_factory = GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_xRGB ";" + GST_VIDEO_CAPS_RGBA ";" + GST_VIDEO_CAPS_BGRA ";" + GST_VIDEO_CAPS_ARGB ";" + GST_VIDEO_CAPS_ABGR ";" GST_VIDEO_CAPS_YUV ("{AYUV, I420, UYVY, NV12, NV21}")) ); @@ -1470,6 +1478,36 @@ gst_text_overlay_shade_xRGB (GstTextOverlay * overlay, guchar * dest, } } +#define ARGB_SHADE_FUNCTION(name, OFFSET) \ +static inline void \ +gst_text_overlay_shade_##name (GstTextOverlay * overlay, guchar * dest, \ +gint x0, gint x1, gint y0, gint y1) \ +{ \ + gint i, j;\ + \ + x0 = CLAMP (x0 - BOX_XPAD, 0, overlay->width);\ + x1 = CLAMP (x1 + BOX_XPAD, 0, overlay->width);\ + \ + y0 = CLAMP (y0 - BOX_YPAD, 0, overlay->height);\ + y1 = CLAMP (y1 + BOX_YPAD, 0, overlay->height);\ + \ + for (i = y0; i < y1; i++) {\ + for (j = x0; j < x1; j++) {\ + gint y, y_pos, k;\ + y_pos = (i * 4 * overlay->width) + j * 4;\ + for (k = OFFSET; k < 3+OFFSET; k++) {\ + y = dest[y_pos + k] + overlay->shading_value;\ + dest[y_pos + k] = CLAMP (y, 0, 255);\ + }\ + }\ + }\ +} +ARGB_SHADE_FUNCTION (ARGB, 1); +ARGB_SHADE_FUNCTION (ABGR, 1); +ARGB_SHADE_FUNCTION (RGBA, 0); +ARGB_SHADE_FUNCTION (BGRA, 0); + + /* FIXME: * - use proper strides and offset for I420 * - don't draw over the edge of the picture (try a longer @@ -1722,6 +1760,55 @@ gst_text_overlay_blit_##name (GstTextOverlay * overlay, \ xRGB_BLIT_FUNCTION (xRGB, 1, 2, 3); xRGB_BLIT_FUNCTION (BGRx, 2, 1, 0); +#define ARGB_BLIT_FUNCTION(name, A, R, G, B) \ +static inline void \ +gst_text_overlay_blit_##name (GstTextOverlay * overlay, \ + guint8 * rgb_pixels, gint xpos, gint ypos) \ +{ \ + int a, r, g, b, a1; \ + 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); \ + a1 = a + (dest[A] * (255 - a)) / 255 + 1; \ + OVER (dest[R], a, r, dest[0], dest[R], a1); \ + OVER (dest[G], a, g, dest[0], dest[G], a1); \ + OVER (dest[B], a, b, dest[0], dest[B], a1); \ + dest[A] = a1 - 1; \ + pimage += 4; \ + dest += 4; \ + } \ + } \ +} +ARGB_BLIT_FUNCTION (RGBA, 3, 0, 1, 2); +ARGB_BLIT_FUNCTION (BGRA, 3, 2, 1, 0); +ARGB_BLIT_FUNCTION (ARGB, 0, 1, 2, 3); +ARGB_BLIT_FUNCTION (ABGR, 0, 3, 2, 1); + static void gst_text_overlay_render_text (GstTextOverlay * overlay, const gchar * text, gint textlen) @@ -1849,6 +1936,26 @@ gst_text_overlay_push_frame (GstTextOverlay * overlay, GstBuffer * video_frame) GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width, ypos, ypos + overlay->image_height); break; + case GST_VIDEO_FORMAT_ARGB: + gst_text_overlay_shade_ARGB (overlay, + GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width, + ypos, ypos + overlay->image_height); + break; + case GST_VIDEO_FORMAT_ABGR: + gst_text_overlay_shade_ABGR (overlay, + GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width, + ypos, ypos + overlay->image_height); + break; + case GST_VIDEO_FORMAT_RGBA: + gst_text_overlay_shade_RGBA (overlay, + GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width, + ypos, ypos + overlay->image_height); + break; + case GST_VIDEO_FORMAT_BGRA: + gst_text_overlay_shade_BGRA (overlay, + GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width, + ypos, ypos + overlay->image_height); + break; default: g_assert_not_reached (); } @@ -1884,6 +1991,22 @@ gst_text_overlay_push_frame (GstTextOverlay * overlay, GstBuffer * video_frame) gst_text_overlay_blit_xRGB (overlay, GST_BUFFER_DATA (video_frame), xpos, ypos); break; + case GST_VIDEO_FORMAT_ARGB: + gst_text_overlay_blit_ARGB (overlay, + GST_BUFFER_DATA (video_frame), xpos, ypos); + break; + case GST_VIDEO_FORMAT_ABGR: + gst_text_overlay_blit_ABGR (overlay, + GST_BUFFER_DATA (video_frame), xpos, ypos); + break; + case GST_VIDEO_FORMAT_RGBA: + gst_text_overlay_blit_RGBA (overlay, + GST_BUFFER_DATA (video_frame), xpos, ypos); + break; + case GST_VIDEO_FORMAT_BGRA: + gst_text_overlay_blit_BGRA (overlay, + GST_BUFFER_DATA (video_frame), xpos, ypos); + break; default: g_assert_not_reached (); }