diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c index aa492e92db..0dd8a102d1 100644 --- a/ext/pango/gsttextoverlay.c +++ b/ext/pango/gsttextoverlay.c @@ -186,7 +186,8 @@ static GstStaticPadTemplate src_template_factory = GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";" - GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_YUV ("{I420, UYVY, NV12, NV21}")) + GST_VIDEO_CAPS_xRGB ";" + GST_VIDEO_CAPS_YUV ("{AYUV, I420, UYVY, NV12, NV21}")) ); static GstStaticPadTemplate video_sink_template_factory = @@ -194,7 +195,8 @@ static GstStaticPadTemplate video_sink_template_factory = GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";" - GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_YUV ("{I420, UYVY, NV12, NV21}")) + GST_VIDEO_CAPS_xRGB ";" + GST_VIDEO_CAPS_YUV ("{AYUV, I420, UYVY, NV12, NV21}")) ); static GstStaticPadTemplate text_sink_template_factory = @@ -1360,7 +1362,7 @@ gst_text_overlay_render_pangocairo (GstTextOverlay * overlay, #define BOX_YPAD 6 static inline void -gst_text_overlay_shade_Y (GstTextOverlay * overlay, guchar * dest, +gst_text_overlay_shade_planar_Y (GstTextOverlay * overlay, guchar * dest, gint x0, gint x1, gint y0, gint y1) { gint i, j, dest_stride; @@ -1384,12 +1386,18 @@ gst_text_overlay_shade_Y (GstTextOverlay * overlay, guchar * dest, } static inline void -gst_text_overlay_shade_UYVY_y (GstTextOverlay * overlay, guchar * dest, +gst_text_overlay_shade_packed_Y (GstTextOverlay * overlay, guchar * dest, gint x0, gint x1, gint y0, gint y1) { gint i, j; - guint dest_stride = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_UYVY, 0, + guint dest_stride, pixel_stride, component_offset; + + dest_stride = gst_video_format_get_row_stride (overlay->format, 0, overlay->width); + pixel_stride = gst_video_format_get_pixel_stride (overlay->format, 0); + component_offset = + gst_video_format_get_component_offset (overlay->format, 0, overlay->width, + overlay->height); x0 = CLAMP (x0 - BOX_XPAD, 0, overlay->width); x1 = CLAMP (x1 + BOX_XPAD, 0, overlay->width); @@ -1397,12 +1405,22 @@ gst_text_overlay_shade_UYVY_y (GstTextOverlay * overlay, guchar * dest, y0 = CLAMP (y0 - BOX_YPAD, 0, overlay->height); y1 = CLAMP (y1 + BOX_YPAD, 0, overlay->height); + if (x0 != 0) + x0 = gst_video_format_get_component_width (overlay->format, 0, x0); + if (x1 != 0) + x1 = gst_video_format_get_component_width (overlay->format, 0, x1); + + if (y0 != 0) + y0 = gst_video_format_get_component_height (overlay->format, 0, y0); + if (y1 != 0) + y1 = gst_video_format_get_component_height (overlay->format, 0, y1); + for (i = y0; i < y1; i++) { for (j = x0; j < x1; j++) { gint y; gint y_pos; - y_pos = (i * dest_stride) + j * 2 + 1; + y_pos = (i * dest_stride) + j * pixel_stride + component_offset; y = dest[y_pos] + overlay->shading_value; dest[y_pos] = CLAMP (y, 0, 255); @@ -1585,6 +1603,57 @@ gst_text_overlay_blit_UYVY (GstTextOverlay * overlay, } } +static inline void +gst_text_overlay_blit_AYUV (GstTextOverlay * overlay, + guint8 * rgb_pixels, gint xpos, gint ypos) +{ + int a, r, g, b; + int y, u, v; + 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); + + COMP_Y (y, r, g, b); + COMP_U (u, r, g, b); + COMP_V (v, r, g, b); + + a = (a * dest[0] + 128) >> 8; + BLEND (dest[1], a, y, dest[1]); + BLEND (dest[2], a, u, dest[2]); + BLEND (dest[3], a, v, dest[3]); + + pimage += 4; + dest += 4; + } + } +} + #define xRGB_BLIT_FUNCTION(name, R, G, B) \ static inline void \ gst_text_overlay_blit_##name (GstTextOverlay * overlay, \ @@ -1738,12 +1807,13 @@ gst_text_overlay_push_frame (GstTextOverlay * overlay, GstBuffer * video_frame) case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_NV12: case GST_VIDEO_FORMAT_NV21: - gst_text_overlay_shade_Y (overlay, + gst_text_overlay_shade_planar_Y (overlay, GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width, ypos, ypos + overlay->image_height); break; + case GST_VIDEO_FORMAT_AYUV: case GST_VIDEO_FORMAT_UYVY: - gst_text_overlay_shade_UYVY_y (overlay, + gst_text_overlay_shade_packed_Y (overlay, GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width, ypos, ypos + overlay->image_height); break; @@ -1780,6 +1850,10 @@ gst_text_overlay_push_frame (GstTextOverlay * overlay, GstBuffer * video_frame) gst_text_overlay_blit_UYVY (overlay, GST_BUFFER_DATA (video_frame), xpos, ypos); break; + case GST_VIDEO_FORMAT_AYUV: + gst_text_overlay_blit_AYUV (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);