PROP_0,
PROP_LOCATION,
PROP_PIXBUF,
+ PROP_POSITIONING_MODE,
PROP_OFFSET_X,
PROP_OFFSET_Y,
PROP_RELATIVE_X,
"IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, " \
"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",
GST_PAD_SINK,
GST_PAD_ALWAYS,
G_DEFINE_TYPE (GstGdkPixbufOverlay, gst_gdk_pixbuf_overlay,
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
gst_gdk_pixbuf_overlay_class_init (GstGdkPixbufOverlayClass * klass)
{
g_param_spec_object ("pixbuf", "Pixbuf", "GdkPixbuf object to render",
GDK_TYPE_PIXBUF, GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING
| 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_static_pad_template_get (&sink_template));
overlay->relative_x = 0.0;
overlay->relative_y = 0.0;
+ overlay->positioning_mode = DEFAULT_POSITIONING_MODE;
+
overlay->overlay_width = 0;
overlay->overlay_height = 0;
overlay->alpha = g_value_get_double (value);
overlay->update_composition = TRUE;
break;
+ case PROP_POSITIONING_MODE:
+ overlay->positioning_mode = g_value_get_enum (value);
+ overlay->update_composition = TRUE;
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
case PROP_ALPHA:
g_value_set_double (value, overlay->alpha);
break;
+ case PROP_POSITIONING_MODE:
+ g_value_set_enum (value, overlay->positioning_mode);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
static void
gst_gdk_pixbuf_overlay_update_composition (GstGdkPixbufOverlay * overlay)
{
+ GstGdkPixbufPositioningMode positioning_mode;
GstVideoOverlayComposition *comp;
GstVideoOverlayRectangle *rect;
GstVideoMeta *overlay_meta;
overlay_meta = gst_buffer_get_video_meta (overlay->pixels);
- x = overlay->offset_x < 0 ?
- 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);
+ positioning_mode = overlay->positioning_mode;
+
+ if (positioning_mode == GST_GDK_PIXBUF_POSITIONING_PIXELS_ABSOLUTE) {
+ x = overlay->offset_x + (overlay->relative_x * overlay_meta->width);
+ y = overlay->offset_y + (overlay->relative_y * overlay_meta->height);
+ } else {
+ x = overlay->offset_x < 0 ?
+ 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;
if (width == 0)