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 =
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);
}
}
}
+#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
}
}
+#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)
/* 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 ();
}
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 ();
}