mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 06:58:56 +00:00
cairooverlay: Don't map input buffers if we just attach the overlay as meta
https://bugzilla.gnome.org/show_bug.cgi?id=797091
This commit is contained in:
parent
10446bd371
commit
a766dce53d
2 changed files with 45 additions and 33 deletions
|
@ -117,7 +117,7 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_STATIC_CAPS (TEMPLATE_CAPS)
|
GST_STATIC_CAPS (TEMPLATE_CAPS)
|
||||||
);
|
);
|
||||||
|
|
||||||
G_DEFINE_TYPE (GstCairoOverlay, gst_cairo_overlay, GST_TYPE_VIDEO_FILTER);
|
G_DEFINE_TYPE (GstCairoOverlay, gst_cairo_overlay, GST_TYPE_BASE_TRANSFORM);
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -211,10 +211,13 @@ gst_cairo_overlay_query (GstBaseTransform * trans, GstPadDirection direction,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_cairo_overlay_set_info (GstVideoFilter * vfilter, GstCaps * in_caps,
|
gst_cairo_overlay_set_caps (GstBaseTransform * trans, GstCaps * in_caps,
|
||||||
GstVideoInfo * in_info, GstCaps * out_caps, GstVideoInfo * out_info)
|
GstCaps * out_caps)
|
||||||
{
|
{
|
||||||
GstCairoOverlay *overlay = GST_CAIRO_OVERLAY (vfilter);
|
GstCairoOverlay *overlay = GST_CAIRO_OVERLAY (trans);
|
||||||
|
|
||||||
|
if (!gst_video_info_from_caps (&overlay->info, in_caps))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
g_signal_emit (overlay, gst_cairo_overlay_signals[SIGNAL_CAPS_CHANGED], 0,
|
g_signal_emit (overlay, gst_cairo_overlay_signals[SIGNAL_CAPS_CHANGED], 0,
|
||||||
in_caps, NULL);
|
in_caps, NULL);
|
||||||
|
@ -347,16 +350,16 @@ gst_video_overlay_rectangle_unpremultiply (GstVideoFrame * frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_cairo_overlay_transform_frame_ip (GstVideoFilter * vfilter,
|
gst_cairo_overlay_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
|
||||||
GstVideoFrame * frame)
|
|
||||||
{
|
{
|
||||||
GstCairoOverlay *overlay = GST_CAIRO_OVERLAY (vfilter);
|
GstCairoOverlay *overlay = GST_CAIRO_OVERLAY (trans);
|
||||||
|
GstVideoFrame frame;
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
cairo_format_t format;
|
cairo_format_t format;
|
||||||
gboolean draw_on_transparent_surface = overlay->draw_on_transparent_surface;
|
gboolean draw_on_transparent_surface = overlay->draw_on_transparent_surface;
|
||||||
|
|
||||||
switch (GST_VIDEO_FRAME_FORMAT (frame)) {
|
switch (GST_VIDEO_INFO_FORMAT (&overlay->info)) {
|
||||||
case GST_VIDEO_FORMAT_ARGB:
|
case GST_VIDEO_FORMAT_ARGB:
|
||||||
case GST_VIDEO_FORMAT_BGRA:
|
case GST_VIDEO_FORMAT_BGRA:
|
||||||
format = CAIRO_FORMAT_ARGB32;
|
format = CAIRO_FORMAT_ARGB32;
|
||||||
|
@ -371,23 +374,33 @@ gst_cairo_overlay_transform_frame_ip (GstVideoFilter * vfilter,
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
GST_WARNING ("No matching cairo format for %s",
|
GST_WARNING ("No matching cairo format for %s",
|
||||||
gst_video_format_to_string (GST_VIDEO_FRAME_FORMAT (frame)));
|
gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&overlay->info)));
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we need to map the buffer writable, do so */
|
||||||
|
if (!draw_on_transparent_surface || !overlay->attach_compo_to_buffer) {
|
||||||
|
if (!gst_video_frame_map (&frame, &overlay->info, buf, GST_MAP_READWRITE)) {
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
frame.buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (draw_on_transparent_surface) {
|
if (draw_on_transparent_surface) {
|
||||||
surface =
|
surface =
|
||||||
cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||||
GST_VIDEO_FRAME_WIDTH (frame), GST_VIDEO_FRAME_HEIGHT (frame));
|
GST_VIDEO_INFO_WIDTH (&overlay->info),
|
||||||
|
GST_VIDEO_INFO_HEIGHT (&overlay->info));
|
||||||
} else {
|
} else {
|
||||||
if (format == CAIRO_FORMAT_ARGB32)
|
if (format == CAIRO_FORMAT_ARGB32)
|
||||||
gst_video_overlay_rectangle_premultiply (frame);
|
gst_video_overlay_rectangle_premultiply (&frame);
|
||||||
|
|
||||||
surface =
|
surface =
|
||||||
cairo_image_surface_create_for_data (GST_VIDEO_FRAME_PLANE_DATA (frame,
|
cairo_image_surface_create_for_data (GST_VIDEO_FRAME_PLANE_DATA (&frame,
|
||||||
0), format, GST_VIDEO_FRAME_WIDTH (frame),
|
0), format, GST_VIDEO_FRAME_WIDTH (&frame),
|
||||||
GST_VIDEO_FRAME_HEIGHT (frame), GST_VIDEO_FRAME_PLANE_STRIDE (frame,
|
GST_VIDEO_FRAME_HEIGHT (&frame), GST_VIDEO_FRAME_PLANE_STRIDE (&frame,
|
||||||
0));
|
0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,8 +414,7 @@ gst_cairo_overlay_transform_frame_ip (GstVideoFilter * vfilter,
|
||||||
}
|
}
|
||||||
|
|
||||||
g_signal_emit (overlay, gst_cairo_overlay_signals[SIGNAL_DRAW], 0,
|
g_signal_emit (overlay, gst_cairo_overlay_signals[SIGNAL_DRAW], 0,
|
||||||
cr, GST_BUFFER_PTS (frame->buffer), GST_BUFFER_DURATION (frame->buffer),
|
cr, GST_BUFFER_PTS (buf), GST_BUFFER_DURATION (buf), NULL);
|
||||||
NULL);
|
|
||||||
|
|
||||||
cairo_destroy (cr);
|
cairo_destroy (cr);
|
||||||
|
|
||||||
|
@ -427,19 +439,19 @@ gst_cairo_overlay_transform_frame_ip (GstVideoFilter * vfilter,
|
||||||
gst_buffer_add_video_meta_full (surface_buffer, GST_VIDEO_FRAME_FLAG_NONE,
|
gst_buffer_add_video_meta_full (surface_buffer, GST_VIDEO_FRAME_FLAG_NONE,
|
||||||
(G_BYTE_ORDER ==
|
(G_BYTE_ORDER ==
|
||||||
G_LITTLE_ENDIAN ? GST_VIDEO_FORMAT_BGRA : GST_VIDEO_FORMAT_ARGB),
|
G_LITTLE_ENDIAN ? GST_VIDEO_FORMAT_BGRA : GST_VIDEO_FORMAT_ARGB),
|
||||||
GST_VIDEO_FRAME_WIDTH (frame), GST_VIDEO_FRAME_HEIGHT (frame), 1,
|
GST_VIDEO_INFO_WIDTH (&overlay->info),
|
||||||
offset, stride);
|
GST_VIDEO_INFO_HEIGHT (&overlay->info), 1, offset, stride);
|
||||||
rect =
|
rect =
|
||||||
gst_video_overlay_rectangle_new_raw (surface_buffer, 0, 0,
|
gst_video_overlay_rectangle_new_raw (surface_buffer, 0, 0,
|
||||||
GST_VIDEO_FRAME_WIDTH (frame), GST_VIDEO_FRAME_HEIGHT (frame),
|
GST_VIDEO_INFO_WIDTH (&overlay->info),
|
||||||
|
GST_VIDEO_INFO_HEIGHT (&overlay->info),
|
||||||
GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA);
|
GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA);
|
||||||
gst_buffer_unref (surface_buffer);
|
gst_buffer_unref (surface_buffer);
|
||||||
|
|
||||||
if (overlay->attach_compo_to_buffer) {
|
if (overlay->attach_compo_to_buffer) {
|
||||||
GstVideoOverlayCompositionMeta *composition_meta;
|
GstVideoOverlayCompositionMeta *composition_meta;
|
||||||
|
|
||||||
composition_meta =
|
composition_meta = gst_buffer_get_video_overlay_composition_meta (buf);
|
||||||
gst_buffer_get_video_overlay_composition_meta (frame->buffer);
|
|
||||||
if (composition_meta) {
|
if (composition_meta) {
|
||||||
GstVideoOverlayComposition *merged_composition =
|
GstVideoOverlayComposition *merged_composition =
|
||||||
gst_video_overlay_composition_copy (composition_meta->overlay);
|
gst_video_overlay_composition_copy (composition_meta->overlay);
|
||||||
|
@ -450,20 +462,23 @@ gst_cairo_overlay_transform_frame_ip (GstVideoFilter * vfilter,
|
||||||
} else {
|
} else {
|
||||||
composition = gst_video_overlay_composition_new (rect);
|
composition = gst_video_overlay_composition_new (rect);
|
||||||
gst_video_overlay_rectangle_unref (rect);
|
gst_video_overlay_rectangle_unref (rect);
|
||||||
gst_buffer_add_video_overlay_composition_meta (frame->buffer,
|
gst_buffer_add_video_overlay_composition_meta (buf, composition);
|
||||||
composition);
|
|
||||||
gst_video_overlay_composition_unref (composition);
|
gst_video_overlay_composition_unref (composition);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
composition = gst_video_overlay_composition_new (rect);
|
composition = gst_video_overlay_composition_new (rect);
|
||||||
gst_video_overlay_rectangle_unref (rect);
|
gst_video_overlay_rectangle_unref (rect);
|
||||||
gst_video_overlay_composition_blend (composition, frame);
|
gst_video_overlay_composition_blend (composition, &frame);
|
||||||
gst_video_overlay_composition_unref (composition);
|
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)
|
||||||
gst_video_overlay_rectangle_unpremultiply (frame);
|
gst_video_overlay_rectangle_unpremultiply (&frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame.buffer) {
|
||||||
|
gst_video_frame_unmap (&frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
@ -472,19 +487,16 @@ gst_cairo_overlay_transform_frame_ip (GstVideoFilter * vfilter,
|
||||||
static void
|
static void
|
||||||
gst_cairo_overlay_class_init (GstCairoOverlayClass * klass)
|
gst_cairo_overlay_class_init (GstCairoOverlayClass * klass)
|
||||||
{
|
{
|
||||||
GstVideoFilterClass *vfilter_class;
|
|
||||||
GstBaseTransformClass *btrans_class;
|
GstBaseTransformClass *btrans_class;
|
||||||
GstElementClass *element_class;
|
GstElementClass *element_class;
|
||||||
GObjectClass *gobject_class;
|
GObjectClass *gobject_class;
|
||||||
|
|
||||||
vfilter_class = (GstVideoFilterClass *) klass;
|
|
||||||
btrans_class = (GstBaseTransformClass *) 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;
|
btrans_class->set_caps = gst_cairo_overlay_set_caps;
|
||||||
vfilter_class->transform_frame_ip = gst_cairo_overlay_transform_frame_ip;
|
btrans_class->transform_ip = gst_cairo_overlay_transform_ip;
|
||||||
|
|
||||||
btrans_class->query = gst_cairo_overlay_query;
|
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;
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
#include <gst/video/gstvideofilter.h>
|
|
||||||
|
|
||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
#include <cairo-gobject.h>
|
#include <cairo-gobject.h>
|
||||||
|
@ -44,17 +43,18 @@ typedef struct _GstCairoOverlay GstCairoOverlay;
|
||||||
typedef struct _GstCairoOverlayClass GstCairoOverlayClass;
|
typedef struct _GstCairoOverlayClass GstCairoOverlayClass;
|
||||||
|
|
||||||
struct _GstCairoOverlay {
|
struct _GstCairoOverlay {
|
||||||
GstVideoFilter video_filter;
|
GstBaseTransform parent;
|
||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
gboolean draw_on_transparent_surface;
|
gboolean draw_on_transparent_surface;
|
||||||
|
|
||||||
/* state */
|
/* state */
|
||||||
|
GstVideoInfo info;
|
||||||
gboolean attach_compo_to_buffer;
|
gboolean attach_compo_to_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstCairoOverlayClass {
|
struct _GstCairoOverlayClass {
|
||||||
GstVideoFilterClass video_filter_class;
|
GstBaseTransformClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_cairo_overlay_get_type (void);
|
GType gst_cairo_overlay_get_type (void);
|
||||||
|
|
Loading…
Reference in a new issue