mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
video-blend: fix blending of rectangles partially or fully outside of the video
In case of overlay being completely or partially outside the video frame, the offset calculations are not right, which resulted in the overlay not being displayed as expected, or crashes due to invalid memory access. When the overlay rectangle is completely outside, we need not render the overlay at all. For partial display of overlay rectangles, src_yoff was not being calculated, hence it was always clipping the bottom half of the overlay, By calculating the src_yoff, now the overlay is clipped properly. https://bugzilla.gnome.org/show_bug.cgi?id=739281
This commit is contained in:
parent
7f5aa9af04
commit
9032c12e69
1 changed files with 23 additions and 10 deletions
|
@ -263,8 +263,8 @@ gboolean
|
|||
gst_video_blend (GstVideoFrame * dest,
|
||||
GstVideoFrame * src, gint x, gint y, gfloat global_alpha)
|
||||
{
|
||||
guint i, j, global_alpha_val, src_width, src_height, dest_width, dest_height;
|
||||
gint xoff;
|
||||
gint i, j, global_alpha_val, src_width, src_height, dest_width, dest_height;
|
||||
gint src_xoff = 0, src_yoff = 0;
|
||||
guint8 *tmpdestline = NULL, *tmpsrcline = NULL;
|
||||
gboolean src_premultiplied_alpha, dest_premultiplied_alpha;
|
||||
void (*matrix) (guint8 * tmpline, guint width);
|
||||
|
@ -292,6 +292,12 @@ gst_video_blend (GstVideoFrame * dest,
|
|||
|
||||
ensure_debug_category ();
|
||||
|
||||
/* In case overlay is completely outside the video, dont render */
|
||||
if (x + src_width <= 0 || y + src_height <= 0
|
||||
|| x >= dest_width || y >= dest_height) {
|
||||
goto nothing_to_do;
|
||||
}
|
||||
|
||||
dinfo = gst_video_format_get_info (GST_VIDEO_FRAME_FORMAT (dest));
|
||||
sinfo = gst_video_format_get_info (GST_VIDEO_FRAME_FORMAT (src));
|
||||
|
||||
|
@ -326,17 +332,18 @@ gst_video_blend (GstVideoFrame * dest,
|
|||
}
|
||||
}
|
||||
|
||||
xoff = 0;
|
||||
|
||||
/* adjust src pointers for negative sizes */
|
||||
/* If we're here we know that the overlay image fully or
|
||||
* partially overlaps with the video frame */
|
||||
/* adjust src image for negative offsets */
|
||||
if (x < 0) {
|
||||
src_width -= -x;
|
||||
src_xoff = -x;
|
||||
src_width -= src_xoff;
|
||||
x = 0;
|
||||
xoff = -x;
|
||||
}
|
||||
|
||||
if (y < 0) {
|
||||
src_height -= -y;
|
||||
src_yoff = -y;
|
||||
src_height -= src_yoff;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
|
@ -348,12 +355,12 @@ gst_video_blend (GstVideoFrame * dest,
|
|||
src_height = dest_height - y;
|
||||
|
||||
/* Mainloop doing the needed conversions, and blending */
|
||||
for (i = y; i < y + src_height; i++) {
|
||||
for (i = y; i < y + src_height; i++, src_yoff++) {
|
||||
|
||||
dinfo->unpack_func (dinfo, 0, tmpdestline, dest->data, dest->info.stride,
|
||||
0, i, dest_width);
|
||||
sinfo->unpack_func (sinfo, 0, tmpsrcline, src->data, src->info.stride,
|
||||
xoff, i - y, src_width - xoff);
|
||||
src_xoff, src_yoff, src_width);
|
||||
|
||||
matrix (tmpsrcline, src_width);
|
||||
|
||||
|
@ -428,4 +435,10 @@ unpack_format_not_supported:
|
|||
gst_video_format_to_string (dinfo->unpack_format));
|
||||
return FALSE;
|
||||
}
|
||||
nothing_to_do:
|
||||
{
|
||||
GST_LOG
|
||||
("Overlay completely outside the video surface, hence not rendering");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue