pango: Add support for xRGB and BGRx formats
This commit is contained in:
parent
67954aeba3
commit
8c874a7ff3
@ -179,16 +179,18 @@ static GstStaticPadTemplate src_template_factory =
|
|||||||
GST_STATIC_PAD_TEMPLATE ("src",
|
GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_SRC,
|
GST_PAD_SRC,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420") ";"
|
GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";"
|
||||||
GST_VIDEO_CAPS_YUV ("UYVY"))
|
GST_VIDEO_CAPS_xRGB ";"
|
||||||
|
GST_VIDEO_CAPS_YUV ("I420") ";" GST_VIDEO_CAPS_YUV ("UYVY"))
|
||||||
);
|
);
|
||||||
|
|
||||||
static GstStaticPadTemplate video_sink_template_factory =
|
static GstStaticPadTemplate video_sink_template_factory =
|
||||||
GST_STATIC_PAD_TEMPLATE ("video_sink",
|
GST_STATIC_PAD_TEMPLATE ("video_sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420") ";"
|
GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";"
|
||||||
GST_VIDEO_CAPS_YUV ("UYVY"))
|
GST_VIDEO_CAPS_xRGB ";"
|
||||||
|
GST_VIDEO_CAPS_YUV ("I420") ";" GST_VIDEO_CAPS_YUV ("UYVY"))
|
||||||
);
|
);
|
||||||
|
|
||||||
static GstStaticPadTemplate text_sink_template_factory =
|
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);
|
structure = gst_caps_get_structure (caps, 0);
|
||||||
fps = gst_structure_get_value (structure, "framerate");
|
fps = gst_structure_get_value (structure, "framerate");
|
||||||
|
|
||||||
if (gst_structure_get_int (structure, "width", &overlay->width) &&
|
if (fps
|
||||||
gst_structure_get_int (structure, "height", &overlay->height) &&
|
&& gst_video_format_parse_caps (caps, &overlay->format, &overlay->width,
|
||||||
gst_structure_get_fourcc (structure, "format", &overlay->format) &&
|
&overlay->height)) {
|
||||||
fps != NULL) {
|
|
||||||
ret = gst_pad_set_caps (overlay->srcpad, caps);
|
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:
|
/* FIXME:
|
||||||
* - use proper strides and offset for I420
|
* - use proper strides and offset for I420
|
||||||
* - don't draw over the edge of the picture (try a longer
|
* - 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
|
static void
|
||||||
gst_text_overlay_render_text (GstTextOverlay * overlay,
|
gst_text_overlay_render_text (GstTextOverlay * overlay,
|
||||||
const gchar * text, gint textlen)
|
const gchar * text, gint textlen)
|
||||||
@ -1515,16 +1587,26 @@ gst_text_overlay_push_frame (GstTextOverlay * overlay, GstBuffer * video_frame)
|
|||||||
/* shaded background box */
|
/* shaded background box */
|
||||||
if (overlay->want_shading) {
|
if (overlay->want_shading) {
|
||||||
switch (overlay->format) {
|
switch (overlay->format) {
|
||||||
case GST_MAKE_FOURCC ('I', '4', '2', '0'):
|
case GST_VIDEO_FORMAT_I420:
|
||||||
gst_text_overlay_shade_I420_y (overlay,
|
gst_text_overlay_shade_I420_y (overlay,
|
||||||
GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
|
GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
|
||||||
ypos, ypos + overlay->image_height);
|
ypos, ypos + overlay->image_height);
|
||||||
break;
|
break;
|
||||||
case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
|
case GST_VIDEO_FORMAT_UYVY:
|
||||||
gst_text_overlay_shade_UYVY_y (overlay,
|
gst_text_overlay_shade_UYVY_y (overlay,
|
||||||
GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
|
GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
|
||||||
ypos, ypos + overlay->image_height);
|
ypos, ypos + overlay->image_height);
|
||||||
break;
|
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:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
@ -1535,14 +1617,22 @@ gst_text_overlay_push_frame (GstTextOverlay * overlay, GstBuffer * video_frame)
|
|||||||
|
|
||||||
if (overlay->text_image) {
|
if (overlay->text_image) {
|
||||||
switch (overlay->format) {
|
switch (overlay->format) {
|
||||||
case GST_MAKE_FOURCC ('I', '4', '2', '0'):
|
case GST_VIDEO_FORMAT_I420:
|
||||||
gst_text_overlay_blit_I420 (overlay,
|
gst_text_overlay_blit_I420 (overlay,
|
||||||
GST_BUFFER_DATA (video_frame), xpos, ypos);
|
GST_BUFFER_DATA (video_frame), xpos, ypos);
|
||||||
break;
|
break;
|
||||||
case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
|
case GST_VIDEO_FORMAT_UYVY:
|
||||||
gst_text_overlay_blit_UYVY (overlay,
|
gst_text_overlay_blit_UYVY (overlay,
|
||||||
GST_BUFFER_DATA (video_frame), xpos, ypos);
|
GST_BUFFER_DATA (video_frame), xpos, ypos);
|
||||||
break;
|
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:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define __GST_TEXT_OVERLAY_H__
|
#define __GST_TEXT_OVERLAY_H__
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
#include <gst/video/video.h>
|
||||||
#include <pango/pangocairo.h>
|
#include <pango/pangocairo.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
@ -109,7 +110,7 @@ struct _GstTextOverlay {
|
|||||||
gint height;
|
gint height;
|
||||||
gint fps_n;
|
gint fps_n;
|
||||||
gint fps_d;
|
gint fps_d;
|
||||||
guint32 format;
|
GstVideoFormat format;
|
||||||
|
|
||||||
GstTextOverlayVAlign valign;
|
GstTextOverlayVAlign valign;
|
||||||
GstTextOverlayHAlign halign;
|
GstTextOverlayHAlign halign;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user