cairooverlay: Add overlay as meta to the buffers if we can

This requires that downstream supports it and
draw-on-transparent-surface is enabled.

https://bugzilla.gnome.org/show_bug.cgi?id=797091
This commit is contained in:
Sebastian Dröge 2018-09-25 17:02:26 +03:00
parent f1c5a22a7a
commit 10446bd371
2 changed files with 67 additions and 6 deletions

View file

@ -176,6 +176,40 @@ gst_cairo_overlay_get_property (GObject * object, guint property_id,
GST_OBJECT_UNLOCK (overlay); GST_OBJECT_UNLOCK (overlay);
} }
static gboolean
gst_cairo_overlay_query (GstBaseTransform * trans, GstPadDirection direction,
GstQuery * query)
{
GstCairoOverlay *overlay = GST_CAIRO_OVERLAY (trans);
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_ALLOCATION:
{
/* We're always running in passthrough mode, which means that
* basetransform just passes through ALLOCATION queries and
* never ever calls BaseTransform::decide_allocation().
*
* We hook into the query handling for that reason
*/
overlay->attach_compo_to_buffer = FALSE;
if (!GST_BASE_TRANSFORM_CLASS (gst_cairo_overlay_parent_class)->query
(trans, direction, query)) {
return FALSE;
}
overlay->attach_compo_to_buffer = gst_query_find_allocation_meta (query,
GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL);
return TRUE;
}
default:
return
GST_BASE_TRANSFORM_CLASS (gst_cairo_overlay_parent_class)->query
(trans, direction, query);
}
}
static gboolean static gboolean
gst_cairo_overlay_set_info (GstVideoFilter * vfilter, GstCaps * in_caps, gst_cairo_overlay_set_info (GstVideoFilter * vfilter, GstCaps * in_caps,
GstVideoInfo * in_info, GstCaps * out_caps, GstVideoInfo * out_info) GstVideoInfo * in_info, GstCaps * out_caps, GstVideoInfo * out_info)
@ -400,14 +434,32 @@ gst_cairo_overlay_transform_frame_ip (GstVideoFilter * vfilter,
GST_VIDEO_FRAME_WIDTH (frame), GST_VIDEO_FRAME_HEIGHT (frame), GST_VIDEO_FRAME_WIDTH (frame), GST_VIDEO_FRAME_HEIGHT (frame),
GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA); GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA);
gst_buffer_unref (surface_buffer); gst_buffer_unref (surface_buffer);
composition = gst_video_overlay_composition_new (rect);
gst_video_overlay_rectangle_unref (rect);
g_assert (gst_video_overlay_composition_blend (composition, frame)); if (overlay->attach_compo_to_buffer) {
GstVideoOverlayCompositionMeta *composition_meta;
gst_video_overlay_composition_unref (composition); composition_meta =
gst_buffer_get_video_overlay_composition_meta (frame->buffer);
/* TODO: Put as meta on the buffer */ if (composition_meta) {
GstVideoOverlayComposition *merged_composition =
gst_video_overlay_composition_copy (composition_meta->overlay);
gst_video_overlay_composition_add_rectangle (merged_composition, rect);
gst_video_overlay_composition_unref (composition_meta->overlay);
composition_meta->overlay = merged_composition;
gst_video_overlay_rectangle_unref (rect);
} else {
composition = gst_video_overlay_composition_new (rect);
gst_video_overlay_rectangle_unref (rect);
gst_buffer_add_video_overlay_composition_meta (frame->buffer,
composition);
gst_video_overlay_composition_unref (composition);
}
} else {
composition = gst_video_overlay_composition_new (rect);
gst_video_overlay_rectangle_unref (rect);
gst_video_overlay_composition_blend (composition, frame);
gst_video_overlay_composition_unref (composition);
}
} else { } else {
cairo_surface_destroy (surface); cairo_surface_destroy (surface);
if (format == CAIRO_FORMAT_ARGB32) if (format == CAIRO_FORMAT_ARGB32)
@ -421,16 +473,20 @@ static void
gst_cairo_overlay_class_init (GstCairoOverlayClass * klass) gst_cairo_overlay_class_init (GstCairoOverlayClass * klass)
{ {
GstVideoFilterClass *vfilter_class; GstVideoFilterClass *vfilter_class;
GstBaseTransformClass *btrans_class;
GstElementClass *element_class; GstElementClass *element_class;
GObjectClass *gobject_class; GObjectClass *gobject_class;
vfilter_class = (GstVideoFilterClass *) klass; vfilter_class = (GstVideoFilterClass *) klass;
btrans_class = (GstBaseTransformClass *) klass;
element_class = (GstElementClass *) klass; element_class = (GstElementClass *) klass;
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
vfilter_class->set_info = gst_cairo_overlay_set_info; vfilter_class->set_info = gst_cairo_overlay_set_info;
vfilter_class->transform_frame_ip = gst_cairo_overlay_transform_frame_ip; vfilter_class->transform_frame_ip = gst_cairo_overlay_transform_frame_ip;
btrans_class->query = gst_cairo_overlay_query;
gobject_class->set_property = gst_cairo_overlay_set_property; gobject_class->set_property = gst_cairo_overlay_set_property;
gobject_class->get_property = gst_cairo_overlay_get_property; gobject_class->get_property = gst_cairo_overlay_get_property;

View file

@ -45,7 +45,12 @@ typedef struct _GstCairoOverlayClass GstCairoOverlayClass;
struct _GstCairoOverlay { struct _GstCairoOverlay {
GstVideoFilter video_filter; GstVideoFilter video_filter;
/* properties */
gboolean draw_on_transparent_surface; gboolean draw_on_transparent_surface;
/* state */
gboolean attach_compo_to_buffer;
}; };
struct _GstCairoOverlayClass { struct _GstCairoOverlayClass {