pango: Add support for xRGB and BGRx formats

This commit is contained in:
Sebastian Dröge 2009-08-04 12:46:57 +02:00
parent 67954aeba3
commit 8c874a7ff3
2 changed files with 104 additions and 13 deletions

View file

@ -179,16 +179,18 @@ static GstStaticPadTemplate src_template_factory =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420") ";"
GST_VIDEO_CAPS_YUV ("UYVY"))
GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";"
GST_VIDEO_CAPS_xRGB ";"
GST_VIDEO_CAPS_YUV ("I420") ";" GST_VIDEO_CAPS_YUV ("UYVY"))
);
static GstStaticPadTemplate video_sink_template_factory =
GST_STATIC_PAD_TEMPLATE ("video_sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420") ";"
GST_VIDEO_CAPS_YUV ("UYVY"))
GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";"
GST_VIDEO_CAPS_xRGB ";"
GST_VIDEO_CAPS_YUV ("I420") ";" GST_VIDEO_CAPS_YUV ("UYVY"))
);
static GstStaticPadTemplate text_sink_template_factory =
@ -686,10 +688,9 @@ gst_text_overlay_setcaps (GstPad * pad, GstCaps * caps)
structure = gst_caps_get_structure (caps, 0);
fps = gst_structure_get_value (structure, "framerate");
if (gst_structure_get_int (structure, "width", &overlay->width) &&
gst_structure_get_int (structure, "height", &overlay->height) &&
gst_structure_get_fourcc (structure, "format", &overlay->format) &&
fps != NULL) {
if (fps
&& gst_video_format_parse_caps (caps, &overlay->format, &overlay->width,
&overlay->height)) {
ret = gst_pad_set_caps (overlay->srcpad, caps);
}
@ -1319,6 +1320,32 @@ gst_text_overlay_shade_UYVY_y (GstTextOverlay * overlay, guchar * dest,
}
}
#define gst_text_overlay_shade_BGRx gst_text_overlay_shade_xRGB
static inline void
gst_text_overlay_shade_xRGB (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 = 0; k < 4; k++) {
y = dest[y_pos + k] + overlay->shading_value;
dest[y_pos + k] = CLAMP (y, 0, 255);
}
}
}
}
/* FIXME:
* - use proper strides and offset for I420
* - don't draw over the edge of the picture (try a longer
@ -1426,6 +1453,51 @@ gst_text_overlay_blit_UYVY (GstTextOverlay * overlay,
}
}
#define xRGB_BLIT_FUNCTION(name, 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; \
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] * a + dest[B] * (255-a)) / 255; \
g = (pimage[CAIRO_ARGB_G] * a + dest[G] * (255-a)) / 255; \
r = (pimage[CAIRO_ARGB_R] * a + dest[R] * (255-a)) / 255; \
\
dest[B] = b; \
dest[G] = g; \
dest[R] = r; \
pimage += 4; \
dest += 4; \
} \
} \
}
xRGB_BLIT_FUNCTION (xRGB, 1, 2, 3);
xRGB_BLIT_FUNCTION (BGRx, 2, 1, 0);
static void
gst_text_overlay_render_text (GstTextOverlay * overlay,
const gchar * text, gint textlen)
@ -1515,16 +1587,26 @@ gst_text_overlay_push_frame (GstTextOverlay * overlay, GstBuffer * video_frame)
/* shaded background box */
if (overlay->want_shading) {
switch (overlay->format) {
case GST_MAKE_FOURCC ('I', '4', '2', '0'):
case GST_VIDEO_FORMAT_I420:
gst_text_overlay_shade_I420_y (overlay,
GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
ypos, ypos + overlay->image_height);
break;
case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
case GST_VIDEO_FORMAT_UYVY:
gst_text_overlay_shade_UYVY_y (overlay,
GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
ypos, ypos + overlay->image_height);
break;
case GST_VIDEO_FORMAT_xRGB:
gst_text_overlay_shade_xRGB (overlay,
GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
ypos, ypos + overlay->image_height);
break;
case GST_VIDEO_FORMAT_BGRx:
gst_text_overlay_shade_BGRx (overlay,
GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
ypos, ypos + overlay->image_height);
break;
default:
g_assert_not_reached ();
}
@ -1535,14 +1617,22 @@ gst_text_overlay_push_frame (GstTextOverlay * overlay, GstBuffer * video_frame)
if (overlay->text_image) {
switch (overlay->format) {
case GST_MAKE_FOURCC ('I', '4', '2', '0'):
case GST_VIDEO_FORMAT_I420:
gst_text_overlay_blit_I420 (overlay,
GST_BUFFER_DATA (video_frame), xpos, ypos);
break;
case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
case GST_VIDEO_FORMAT_UYVY:
gst_text_overlay_blit_UYVY (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);
break;
case GST_VIDEO_FORMAT_xRGB:
gst_text_overlay_blit_xRGB (overlay,
GST_BUFFER_DATA (video_frame), xpos, ypos);
break;
default:
g_assert_not_reached ();
}

View file

@ -2,6 +2,7 @@
#define __GST_TEXT_OVERLAY_H__
#include <gst/gst.h>
#include <gst/video/video.h>
#include <pango/pangocairo.h>
G_BEGIN_DECLS
@ -109,7 +110,7 @@ struct _GstTextOverlay {
gint height;
gint fps_n;
gint fps_d;
guint32 format;
GstVideoFormat format;
GstTextOverlayVAlign valign;
GstTextOverlayHAlign halign;