overlay: fix ordering of composition layers.

Make sure to maintain the association order of composition layers when
GstVideoOverlayRectangle objects are kept around (cached).
This commit is contained in:
Gwenole Beauchesne 2013-01-11 15:19:45 +01:00
parent 2ecb955626
commit 7e1a8eabfe

View file

@ -54,6 +54,7 @@ struct _GstVaapiOverlayRectangle {
GstVaapiSubpicture *subpicture; GstVaapiSubpicture *subpicture;
GstVaapiRectangle render_rect; GstVaapiRectangle render_rect;
guint seq_num; guint seq_num;
guint layer_id;
GstBuffer *rect_buffer; GstBuffer *rect_buffer;
GstVideoOverlayRectangle *rect; GstVideoOverlayRectangle *rect;
guint is_associated : 1; guint is_associated : 1;
@ -150,7 +151,8 @@ overlay_rectangle_class(void)
} }
static GstVaapiOverlayRectangle * static GstVaapiOverlayRectangle *
overlay_rectangle_new(GstVideoOverlayRectangle *rect, GstVaapiContext *context) overlay_rectangle_new(GstVideoOverlayRectangle *rect, GstVaapiContext *context,
guint layer_id)
{ {
GstVaapiOverlayRectangle *overlay; GstVaapiOverlayRectangle *overlay;
GstVaapiRectangle *render_rect; GstVaapiRectangle *render_rect;
@ -164,6 +166,7 @@ overlay_rectangle_new(GstVideoOverlayRectangle *rect, GstVaapiContext *context)
overlay->context = context; overlay->context = context;
overlay->seq_num = gst_video_overlay_rectangle_get_seqnum(rect); overlay->seq_num = gst_video_overlay_rectangle_get_seqnum(rect);
overlay->layer_id = layer_id;
overlay->rect = gst_video_overlay_rectangle_ref(rect); overlay->rect = gst_video_overlay_rectangle_ref(rect);
gst_buffer_replace(&overlay->rect_buffer, gst_buffer_replace(&overlay->rect_buffer,
@ -183,11 +186,6 @@ overlay_rectangle_new(GstVideoOverlayRectangle *rect, GstVaapiContext *context)
render_rect->y = y; render_rect->y = y;
render_rect->width = width; render_rect->width = width;
render_rect->height = height; render_rect->height = height;
if (!overlay_rectangle_associate(overlay)) {
GST_WARNING("could not render overlay rectangle %p", rect);
goto error;
}
return overlay; return overlay;
error: error:
@ -270,7 +268,7 @@ overlay_rectangle_changed_pixels(GstVaapiOverlayRectangle *overlay,
} }
static gboolean static gboolean
overlay_rectangle_update_render_rect(GstVaapiOverlayRectangle *overlay, overlay_rectangle_changed_render_rect(GstVaapiOverlayRectangle *overlay,
GstVideoOverlayRectangle *rect) GstVideoOverlayRectangle *rect)
{ {
GstVaapiRectangle * const render_rect = &overlay->render_rect; GstVaapiRectangle * const render_rect = &overlay->render_rect;
@ -284,15 +282,13 @@ overlay_rectangle_update_render_rect(GstVaapiOverlayRectangle *overlay,
y == render_rect->y && y == render_rect->y &&
width == render_rect->width && width == render_rect->width &&
height == render_rect->height) height == render_rect->height)
return TRUE; return FALSE;
overlay_rectangle_deassociate(overlay);
render_rect->x = x; render_rect->x = x;
render_rect->y = y; render_rect->y = y;
render_rect->width = width; render_rect->width = width;
render_rect->height = height; render_rect->height = height;
return overlay_rectangle_associate(overlay); return TRUE;
} }
static inline gboolean static inline gboolean
@ -308,12 +304,12 @@ overlay_rectangle_update_global_alpha(GstVaapiOverlayRectangle *overlay,
static gboolean static gboolean
overlay_rectangle_update(GstVaapiOverlayRectangle *overlay, overlay_rectangle_update(GstVaapiOverlayRectangle *overlay,
GstVideoOverlayRectangle *rect) GstVideoOverlayRectangle *rect, gboolean *reassociate_ptr)
{ {
if (overlay_rectangle_changed_pixels(overlay, rect)) if (overlay_rectangle_changed_pixels(overlay, rect))
return FALSE; return FALSE;
if (!overlay_rectangle_update_render_rect(overlay, rect)) if (overlay_rectangle_changed_render_rect(overlay, rect))
return FALSE; *reassociate_ptr = TRUE;
if (!overlay_rectangle_update_global_alpha(overlay, rect)) if (!overlay_rectangle_update_global_alpha(overlay, rect))
return FALSE; return FALSE;
gst_video_overlay_rectangle_replace(&overlay->rect, rect); gst_video_overlay_rectangle_replace(&overlay->rect, rect);
@ -360,6 +356,21 @@ overlay_lookup(GPtrArray *overlays, GstVideoOverlayRectangle *rect)
return NULL; return NULL;
} }
static gboolean
overlay_reassociate(GPtrArray *overlays)
{
guint i;
for (i = 0; i < overlays->len; i++)
overlay_rectangle_deassociate(g_ptr_array_index(overlays, i));
for (i = 0; i < overlays->len; i++) {
if (!overlay_rectangle_associate(g_ptr_array_index(overlays, i)))
return FALSE;
}
return TRUE;
}
static void static void
gst_vaapi_context_clear_overlay(GstVaapiContext *context) gst_vaapi_context_clear_overlay(GstVaapiContext *context)
{ {
@ -1107,6 +1118,7 @@ gst_vaapi_context_apply_composition(
GstVaapiContextPrivate *priv; GstVaapiContextPrivate *priv;
GPtrArray *curr_overlay, *next_overlay; GPtrArray *curr_overlay, *next_overlay;
guint i, n_rectangles; guint i, n_rectangles;
gboolean reassociate = FALSE;
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), FALSE); g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), FALSE);
@ -1131,20 +1143,27 @@ gst_vaapi_context_apply_composition(
GstVaapiOverlayRectangle *overlay; GstVaapiOverlayRectangle *overlay;
overlay = overlay_lookup(curr_overlay, rect); overlay = overlay_lookup(curr_overlay, rect);
if (overlay && overlay_rectangle_update(overlay, rect)) if (overlay && overlay_rectangle_update(overlay, rect, &reassociate)) {
overlay_rectangle_ref(overlay); overlay_rectangle_ref(overlay);
if (overlay->layer_id != i)
reassociate = TRUE;
}
else { else {
overlay = overlay_rectangle_new(rect, context); overlay = overlay_rectangle_new(rect, context, i);
if (!overlay) { if (!overlay) {
GST_WARNING("could not create VA overlay rectangle"); GST_WARNING("could not create VA overlay rectangle");
goto error; goto error;
} }
reassociate = TRUE;
} }
g_ptr_array_add(next_overlay, overlay); g_ptr_array_add(next_overlay, overlay);
} }
overlay_clear(curr_overlay); overlay_clear(curr_overlay);
priv->overlay_id ^= 1; priv->overlay_id ^= 1;
if (reassociate && !overlay_reassociate(next_overlay))
return FALSE;
return TRUE; return TRUE;
error: error: