summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorLane Brooks <dirjud@gmail.com>2011-01-17 21:12:18 -0700
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2011-04-01 10:36:36 +0200
commit200ee96338e73932074ad977d2187a7b7c163d96 (patch)
tree024949acf1c695df74768c8a4fa28e01eb6f023d /ext
parente2150b11ff8a98a3b7081d8106bca496a91c6b2b (diff)
textoverlay: Added support for ARGB and other RGB alpha variants
Diffstat (limited to 'ext')
-rw-r--r--ext/pango/gsttextoverlay.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c
index 6cd9db7af..1d0f25b84 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 ();
}