Commit e876d9a5 authored by Gwenole Beauchesne's avatar Gwenole Beauchesne

overlay: fix check for pixels buffer change.

A GstVideoOverlayRectangle is created whenever the underlying pixels data
change. However, when global-alpha is supported, it is possible to re-use
the same GstVideoOverlayRectangle but with a change to the global-alpha
value. This process causes a change of sequence number, so we can no longer
check for that.

Still, if sequence numbers did not change, then there was no change in
global-alpha either. So, we need a way to compare the underlying GstBuffer
pointers. There is no API to retrieve the original pixels buffer from
a GstVideoOverlayRectangle. So, we use the following heuristics:

1. Use gst_video_overlay_rectangle_get_pixels_unscaled_argb() with the same
   format flags from which the GstVideoOverlayRectangle was created. This
   will work if there was no prior consumer of the GstVideoOverlayRectangle
   with alternate (non-"native") format flags.

2. In overlay_rectangle_has_changed_pixels(), we have to use the same
   gst_video_overlay_rectangle_get_pixels_unscaled_argb() function but
   with flags that match the subpicture. This is needed to cope with
   platforms that don't support global-alpha in HW, so the gst-video
   layer takes care of that and fixes this up with a possibly new
   GstBuffer, and hence pixels data (or) in-place by caching the current
   global-alpha value applied. So we have to determine the rectangle
   was previously used, based on what previous flags were used to
   retrieve the ARGB pixels buffer.
parent a14d2590
......@@ -54,6 +54,7 @@ struct _GstVaapiOverlayRectangle {
GstVaapiSubpicture *subpicture;
GstVaapiRectangle render_rect;
guint seq_num;
GstBuffer *rect_buffer;
GstVideoOverlayRectangle *rect;
guint is_associated : 1;
};
......@@ -104,6 +105,21 @@ gst_video_overlay_rectangle_replace(GstVideoOverlayRectangle **old_rect_ptr,
GST_MINI_OBJECT_CAST(new_rect));
}
static inline GstBuffer *
gst_video_overlay_rectangle_get_pixels_raw(GstVideoOverlayRectangle *rect)
{
guint width, height, stride, flags;
flags = gst_video_overlay_rectangle_get_flags(rect);
/* Try to retrieve the original buffer that was passed to
gst_video_overlay_rectangle_new_argb(). This will only work if
there was no previous user that required pixels with non native
alpha type */
return gst_video_overlay_rectangle_get_pixels_unscaled_argb(rect,
&width, &height, &stride, flags);
}
#define overlay_rectangle_ref(overlay) \
gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(overlay))
......@@ -150,6 +166,11 @@ overlay_rectangle_new(GstVideoOverlayRectangle *rect, GstVaapiContext *context)
overlay->seq_num = gst_video_overlay_rectangle_get_seqnum(rect);
overlay->rect = gst_video_overlay_rectangle_ref(rect);
gst_buffer_replace(&overlay->rect_buffer,
gst_video_overlay_rectangle_get_pixels_raw(rect));
if (!overlay->rect_buffer)
goto error;
overlay->subpicture = gst_vaapi_subpicture_new_from_overlay_rectangle(
GST_VAAPI_OBJECT_DISPLAY(context), rect);
if (!overlay->subpicture)
......@@ -177,6 +198,7 @@ error:
static void
overlay_rectangle_finalize(GstVaapiOverlayRectangle *overlay)
{
gst_buffer_replace(&overlay->rect_buffer, NULL);
gst_video_overlay_rectangle_unref(overlay->rect);
if (overlay->subpicture) {
......@@ -233,9 +255,18 @@ static gboolean
overlay_rectangle_changed_pixels(GstVaapiOverlayRectangle *overlay,
GstVideoOverlayRectangle *rect)
{
guint width, height, stride, flags;
GstBuffer *buffer;
if (overlay->seq_num == gst_video_overlay_rectangle_get_seqnum(rect))
return FALSE;
return TRUE;
flags = to_GstVideoOverlayFormatFlags(
gst_vaapi_subpicture_get_flags(overlay->subpicture));
buffer = gst_video_overlay_rectangle_get_pixels_unscaled_argb(rect,
&width, &height, &stride, flags);
return GST_BUFFER_DATA(overlay->rect_buffer) != GST_BUFFER_DATA(buffer);
}
static gboolean
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment