mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-04 22:48:54 +00:00
pango: Add support for xRGB and BGRx formats
This commit is contained in:
parent
67954aeba3
commit
8c874a7ff3
2 changed files with 104 additions and 13 deletions
|
@ -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 ();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue