mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 00:58:12 +00:00
gdkpixbufoverlay: add "positioning-mode" property to allow absolute positions
Set positioning-mode=pixels-absolute to allow positioning with absolute coordinates, meaning negative x/y offsets will be interpreted as being to the left/above the video frame instead of being interpreted as relative to the right/bottom edge of the video frame (which is a silly default, but that's how it is). This means we can nicely slide images into and out of the frame, see gdkpixbufoverlay-test. https://bugzilla.gnome.org/show_bug.cgi?id=739566
This commit is contained in:
parent
11d6be2dcb
commit
b76595d67e
2 changed files with 78 additions and 8 deletions
|
@ -81,6 +81,7 @@ enum
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_LOCATION,
|
PROP_LOCATION,
|
||||||
PROP_PIXBUF,
|
PROP_PIXBUF,
|
||||||
|
PROP_POSITIONING_MODE,
|
||||||
PROP_OFFSET_X,
|
PROP_OFFSET_X,
|
||||||
PROP_OFFSET_Y,
|
PROP_OFFSET_Y,
|
||||||
PROP_RELATIVE_X,
|
PROP_RELATIVE_X,
|
||||||
|
@ -97,6 +98,10 @@ enum
|
||||||
"IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, " \
|
"IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, " \
|
||||||
"GRAY8, GRAY16_BE, GRAY16_LE }"
|
"GRAY8, GRAY16_BE, GRAY16_LE }"
|
||||||
|
|
||||||
|
/* FIXME 2.0: change to absolute positioning */
|
||||||
|
#define DEFAULT_POSITIONING_MODE \
|
||||||
|
GST_GDK_PIXBUF_POSITIONING_PIXELS_RELATIVE_TO_EDGES
|
||||||
|
|
||||||
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
|
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
|
@ -112,6 +117,29 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
G_DEFINE_TYPE (GstGdkPixbufOverlay, gst_gdk_pixbuf_overlay,
|
G_DEFINE_TYPE (GstGdkPixbufOverlay, gst_gdk_pixbuf_overlay,
|
||||||
GST_TYPE_VIDEO_FILTER);
|
GST_TYPE_VIDEO_FILTER);
|
||||||
|
|
||||||
|
#define GST_TYPE_GDK_PIXBUF_POSITIONING_MODE \
|
||||||
|
(gst_gdk_pixbuf_positioning_mode_get_type())
|
||||||
|
|
||||||
|
static GType
|
||||||
|
gst_gdk_pixbuf_positioning_mode_get_type (void)
|
||||||
|
{
|
||||||
|
static const GEnumValue pos_modes[] = {
|
||||||
|
{GST_GDK_PIXBUF_POSITIONING_PIXELS_RELATIVE_TO_EDGES,
|
||||||
|
"pixels-relative-to-edges", "pixels-relative-to-edges"},
|
||||||
|
{GST_GDK_PIXBUF_POSITIONING_PIXELS_ABSOLUTE, "pixels-absolute",
|
||||||
|
"pixels-absolute"},
|
||||||
|
{0, NULL, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
static GType type; /* 0 */
|
||||||
|
|
||||||
|
if (!type) {
|
||||||
|
type = g_enum_register_static ("GstGdkPixbufPositioningMode", pos_modes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_gdk_pixbuf_overlay_class_init (GstGdkPixbufOverlayClass * klass)
|
gst_gdk_pixbuf_overlay_class_init (GstGdkPixbufOverlayClass * klass)
|
||||||
{
|
{
|
||||||
|
@ -193,6 +221,24 @@ gst_gdk_pixbuf_overlay_class_init (GstGdkPixbufOverlayClass * klass)
|
||||||
g_param_spec_object ("pixbuf", "Pixbuf", "GdkPixbuf object to render",
|
g_param_spec_object ("pixbuf", "Pixbuf", "GdkPixbuf object to render",
|
||||||
GDK_TYPE_PIXBUF, GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING
|
GDK_TYPE_PIXBUF, GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING
|
||||||
| G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
| G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
/**
|
||||||
|
* GstGdkPixbufOverlay:positioning-mode:
|
||||||
|
*
|
||||||
|
* Positioning mode of offset-x and offset-y properties. Determines how
|
||||||
|
* negative x/y offsets will be interpreted. By default negative values
|
||||||
|
* are for positioning relative to the right/bottom edge of the video
|
||||||
|
* image, but you can use this property to select absolute positioning
|
||||||
|
* relative to a (0, 0) origin in the top-left corner. That way negative
|
||||||
|
* offsets will be to the left/above the video image, which allows you to
|
||||||
|
* smoothly slide logos into and out of the frame if desired.
|
||||||
|
*
|
||||||
|
* Since: 1.6
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class, PROP_POSITIONING_MODE,
|
||||||
|
g_param_spec_enum ("positioning-mode", "Positioning mode",
|
||||||
|
"Positioning mode of offset-x and offset-y properties",
|
||||||
|
GST_TYPE_GDK_PIXBUF_POSITIONING_MODE, DEFAULT_POSITIONING_MODE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
gst_element_class_add_pad_template (element_class,
|
||||||
gst_static_pad_template_get (&sink_template));
|
gst_static_pad_template_get (&sink_template));
|
||||||
|
@ -216,6 +262,8 @@ gst_gdk_pixbuf_overlay_init (GstGdkPixbufOverlay * overlay)
|
||||||
overlay->relative_x = 0.0;
|
overlay->relative_x = 0.0;
|
||||||
overlay->relative_y = 0.0;
|
overlay->relative_y = 0.0;
|
||||||
|
|
||||||
|
overlay->positioning_mode = DEFAULT_POSITIONING_MODE;
|
||||||
|
|
||||||
overlay->overlay_width = 0;
|
overlay->overlay_width = 0;
|
||||||
overlay->overlay_height = 0;
|
overlay->overlay_height = 0;
|
||||||
|
|
||||||
|
@ -281,6 +329,10 @@ gst_gdk_pixbuf_overlay_set_property (GObject * object, guint property_id,
|
||||||
overlay->alpha = g_value_get_double (value);
|
overlay->alpha = g_value_get_double (value);
|
||||||
overlay->update_composition = TRUE;
|
overlay->update_composition = TRUE;
|
||||||
break;
|
break;
|
||||||
|
case PROP_POSITIONING_MODE:
|
||||||
|
overlay->positioning_mode = g_value_get_enum (value);
|
||||||
|
overlay->update_composition = TRUE;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -325,6 +377,9 @@ gst_gdk_pixbuf_overlay_get_property (GObject * object, guint property_id,
|
||||||
case PROP_ALPHA:
|
case PROP_ALPHA:
|
||||||
g_value_set_double (value, overlay->alpha);
|
g_value_set_double (value, overlay->alpha);
|
||||||
break;
|
break;
|
||||||
|
case PROP_POSITIONING_MODE:
|
||||||
|
g_value_set_enum (value, overlay->positioning_mode);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -479,6 +534,7 @@ gst_gdk_pixbuf_overlay_set_info (GstVideoFilter * filter, GstCaps * incaps,
|
||||||
static void
|
static void
|
||||||
gst_gdk_pixbuf_overlay_update_composition (GstGdkPixbufOverlay * overlay)
|
gst_gdk_pixbuf_overlay_update_composition (GstGdkPixbufOverlay * overlay)
|
||||||
{
|
{
|
||||||
|
GstGdkPixbufPositioningMode positioning_mode;
|
||||||
GstVideoOverlayComposition *comp;
|
GstVideoOverlayComposition *comp;
|
||||||
GstVideoOverlayRectangle *rect;
|
GstVideoOverlayRectangle *rect;
|
||||||
GstVideoMeta *overlay_meta;
|
GstVideoMeta *overlay_meta;
|
||||||
|
@ -498,14 +554,21 @@ gst_gdk_pixbuf_overlay_update_composition (GstGdkPixbufOverlay * overlay)
|
||||||
|
|
||||||
overlay_meta = gst_buffer_get_video_meta (overlay->pixels);
|
overlay_meta = gst_buffer_get_video_meta (overlay->pixels);
|
||||||
|
|
||||||
x = overlay->offset_x < 0 ?
|
positioning_mode = overlay->positioning_mode;
|
||||||
video_width + overlay->offset_x - overlay_meta->width +
|
|
||||||
(overlay->relative_x * overlay_meta->width) :
|
if (positioning_mode == GST_GDK_PIXBUF_POSITIONING_PIXELS_ABSOLUTE) {
|
||||||
overlay->offset_x + (overlay->relative_x * overlay_meta->width);
|
x = overlay->offset_x + (overlay->relative_x * overlay_meta->width);
|
||||||
y = overlay->offset_y < 0 ?
|
y = overlay->offset_y + (overlay->relative_y * overlay_meta->height);
|
||||||
video_height + overlay->offset_y - overlay_meta->height +
|
} else {
|
||||||
(overlay->relative_y * overlay_meta->height) :
|
x = overlay->offset_x < 0 ?
|
||||||
overlay->offset_y + (overlay->relative_y * overlay_meta->height);
|
video_width + overlay->offset_x - overlay_meta->width +
|
||||||
|
(overlay->relative_x * overlay_meta->width) :
|
||||||
|
overlay->offset_x + (overlay->relative_x * overlay_meta->width);
|
||||||
|
y = overlay->offset_y < 0 ?
|
||||||
|
video_height + overlay->offset_y - overlay_meta->height +
|
||||||
|
(overlay->relative_y * overlay_meta->height) :
|
||||||
|
overlay->offset_y + (overlay->relative_y * overlay_meta->height);
|
||||||
|
}
|
||||||
|
|
||||||
width = overlay->overlay_width;
|
width = overlay->overlay_width;
|
||||||
if (width == 0)
|
if (width == 0)
|
||||||
|
|
|
@ -37,6 +37,11 @@ G_BEGIN_DECLS
|
||||||
typedef struct _GstGdkPixbufOverlay GstGdkPixbufOverlay;
|
typedef struct _GstGdkPixbufOverlay GstGdkPixbufOverlay;
|
||||||
typedef struct _GstGdkPixbufOverlayClass GstGdkPixbufOverlayClass;
|
typedef struct _GstGdkPixbufOverlayClass GstGdkPixbufOverlayClass;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GST_GDK_PIXBUF_POSITIONING_PIXELS_RELATIVE_TO_EDGES,
|
||||||
|
GST_GDK_PIXBUF_POSITIONING_PIXELS_ABSOLUTE
|
||||||
|
} GstGdkPixbufPositioningMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstGdkPixbufOverlay:
|
* GstGdkPixbufOverlay:
|
||||||
*
|
*
|
||||||
|
@ -58,6 +63,8 @@ struct _GstGdkPixbufOverlay
|
||||||
gdouble relative_x;
|
gdouble relative_x;
|
||||||
gdouble relative_y;
|
gdouble relative_y;
|
||||||
|
|
||||||
|
GstGdkPixbufPositioningMode positioning_mode;
|
||||||
|
|
||||||
gint overlay_width;
|
gint overlay_width;
|
||||||
gint overlay_height;
|
gint overlay_height;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue