mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 10:41:04 +00:00
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.
This commit is contained in:
parent
a14d259060
commit
e876d9a581
1 changed files with 32 additions and 1 deletions
|
@ -54,6 +54,7 @@ struct _GstVaapiOverlayRectangle {
|
||||||
GstVaapiSubpicture *subpicture;
|
GstVaapiSubpicture *subpicture;
|
||||||
GstVaapiRectangle render_rect;
|
GstVaapiRectangle render_rect;
|
||||||
guint seq_num;
|
guint seq_num;
|
||||||
|
GstBuffer *rect_buffer;
|
||||||
GstVideoOverlayRectangle *rect;
|
GstVideoOverlayRectangle *rect;
|
||||||
guint is_associated : 1;
|
guint is_associated : 1;
|
||||||
};
|
};
|
||||||
|
@ -104,6 +105,21 @@ gst_video_overlay_rectangle_replace(GstVideoOverlayRectangle **old_rect_ptr,
|
||||||
GST_MINI_OBJECT_CAST(new_rect));
|
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) \
|
#define overlay_rectangle_ref(overlay) \
|
||||||
gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(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->seq_num = gst_video_overlay_rectangle_get_seqnum(rect);
|
||||||
overlay->rect = gst_video_overlay_rectangle_ref(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(
|
overlay->subpicture = gst_vaapi_subpicture_new_from_overlay_rectangle(
|
||||||
GST_VAAPI_OBJECT_DISPLAY(context), rect);
|
GST_VAAPI_OBJECT_DISPLAY(context), rect);
|
||||||
if (!overlay->subpicture)
|
if (!overlay->subpicture)
|
||||||
|
@ -177,6 +198,7 @@ error:
|
||||||
static void
|
static void
|
||||||
overlay_rectangle_finalize(GstVaapiOverlayRectangle *overlay)
|
overlay_rectangle_finalize(GstVaapiOverlayRectangle *overlay)
|
||||||
{
|
{
|
||||||
|
gst_buffer_replace(&overlay->rect_buffer, NULL);
|
||||||
gst_video_overlay_rectangle_unref(overlay->rect);
|
gst_video_overlay_rectangle_unref(overlay->rect);
|
||||||
|
|
||||||
if (overlay->subpicture) {
|
if (overlay->subpicture) {
|
||||||
|
@ -233,9 +255,18 @@ static gboolean
|
||||||
overlay_rectangle_changed_pixels(GstVaapiOverlayRectangle *overlay,
|
overlay_rectangle_changed_pixels(GstVaapiOverlayRectangle *overlay,
|
||||||
GstVideoOverlayRectangle *rect)
|
GstVideoOverlayRectangle *rect)
|
||||||
{
|
{
|
||||||
|
guint width, height, stride, flags;
|
||||||
|
GstBuffer *buffer;
|
||||||
|
|
||||||
if (overlay->seq_num == gst_video_overlay_rectangle_get_seqnum(rect))
|
if (overlay->seq_num == gst_video_overlay_rectangle_get_seqnum(rect))
|
||||||
return FALSE;
|
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
|
static gboolean
|
||||||
|
|
Loading…
Reference in a new issue