From 1c33b79c0ce6ff1c825cc2492e6519e16cec1f7b Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Mon, 7 Jun 2010 22:21:10 -0300 Subject: [PATCH] geometrictransform: Make properties controllable Makes the element's properties controllable and threadsafe. Fixes #620825 --- gst/geometrictransform/Makefile.am | 10 +++- gst/geometrictransform/gstcircle.c | 30 ++++++++-- .../gstcirclegeometrictransform.c | 44 +++++++++----- gst/geometrictransform/gstdiffuse.c | 13 ++++- .../gstgeometrictransform.c | 57 ++++++++++++++++++- .../gstgeometrictransform.h | 6 ++ gst/geometrictransform/gstkaleidoscope.c | 30 ++++++++-- gst/geometrictransform/gstmarble.c | 37 +++++++++--- gst/geometrictransform/gstpinch.c | 13 ++++- gst/geometrictransform/gstsphere.c | 13 ++++- gst/geometrictransform/gsttwirl.c | 13 ++++- gst/geometrictransform/gstwaterripple.c | 29 ++++++++-- 12 files changed, 243 insertions(+), 52 deletions(-) diff --git a/gst/geometrictransform/Makefile.am b/gst/geometrictransform/Makefile.am index b88932a4c7..b2c9ff7df2 100644 --- a/gst/geometrictransform/Makefile.am +++ b/gst/geometrictransform/Makefile.am @@ -14,8 +14,14 @@ libgstgeometrictransform_la_SOURCES = plugin.c \ gstwaterripple.c libgstgeometrictransform_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) \ - $(GST_PLUGINS_BASE_CFLAGS) -libgstgeometrictransform_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstvideo-@GST_MAJORMINOR@ $(GST_BASE_LIBS) $(GST_LIBS) + $(GST_PLUGINS_BASE_CFLAGS) \ + $(GST_CONTROLLER_CFLAGS) +libgstgeometrictransform_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \ + -lgstvideo-@GST_MAJORMINOR@ \ + -lgstinterfaces-@GST_MAJORMINOR@ \ + $(GST_CONTROLLER_LIBS) \ + $(GST_BASE_LIBS) \ + $(GST_LIBS) $(LIBM) libgstgeometrictransform_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstgeometrictransform_la_LIBTOOLFLAGS = --tag=disable-static diff --git a/gst/geometrictransform/gstcircle.c b/gst/geometrictransform/gstcircle.c index 5b63e30e3d..fe6a99efe3 100644 --- a/gst/geometrictransform/gstcircle.c +++ b/gst/geometrictransform/gstcircle.c @@ -82,23 +82,41 @@ gst_circle_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstCircle *circle; + GstGeometricTransform *gt; + gdouble v; + gint h; + gt = GST_GEOMETRIC_TRANSFORM_CAST (object); circle = GST_CIRCLE_CAST (object); + GST_OBJECT_LOCK (circle); switch (prop_id) { case PROP_ANGLE: - circle->angle = g_value_get_double (value); + v = g_value_get_double (value); + if (v != circle->angle) { + circle->angle = v; + gst_geometric_transform_set_need_remap (gt); + } break; case PROP_SPREAD_ANGLE: - circle->spread_angle = g_value_get_double (value); + v = g_value_get_double (value); + if (v != circle->spread_angle) { + circle->spread_angle = v; + gst_geometric_transform_set_need_remap (gt); + } break; case PROP_HEIGHT: - circle->height = g_value_get_int (value); + h = g_value_get_int (value); + if (h != circle->height) { + circle->height = h; + gst_geometric_transform_set_need_remap (gt); + } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } + GST_OBJECT_UNLOCK (circle); } static void @@ -192,17 +210,17 @@ gst_circle_class_init (GstCircleClass * klass) g_param_spec_double ("angle", "angle", "Angle at which the arc starts in radians", -G_MAXDOUBLE, G_MAXDOUBLE, DEFAULT_ANGLE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_SPREAD_ANGLE, g_param_spec_double ("spread-angle", "spread angle", "Length of the arc in radians", -G_MAXDOUBLE, G_MAXDOUBLE, DEFAULT_SPREAD_ANGLE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_HEIGHT, g_param_spec_int ("height", "height", "Height of the arc", 0, G_MAXINT, DEFAULT_HEIGHT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gstgt_class->map_func = circle_map; } diff --git a/gst/geometrictransform/gstcirclegeometrictransform.c b/gst/geometrictransform/gstcirclegeometrictransform.c index 38690ef352..7f8cf2ecca 100644 --- a/gst/geometrictransform/gstcirclegeometrictransform.c +++ b/gst/geometrictransform/gstcirclegeometrictransform.c @@ -78,43 +78,60 @@ static void gst_circle_geometric_transform_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - GstCircleGeometricTransform *circle_geometric_transform; + GstCircleGeometricTransform *cgt; + GstGeometricTransform *gt; + gdouble v; - circle_geometric_transform = GST_CIRCLE_GEOMETRIC_TRANSFORM_CAST (object); + gt = GST_GEOMETRIC_TRANSFORM_CAST (object); + cgt = GST_CIRCLE_GEOMETRIC_TRANSFORM_CAST (object); + GST_OBJECT_LOCK (cgt); switch (prop_id) { case PROP_X_CENTER: - circle_geometric_transform->x_center = g_value_get_double (value); + v = g_value_get_double (value); + if (v != cgt->x_center) { + cgt->x_center = v; + gst_geometric_transform_set_need_remap (gt); + } break; case PROP_Y_CENTER: - circle_geometric_transform->y_center = g_value_get_double (value); + v = g_value_get_double (value); + if (v != cgt->y_center) { + cgt->y_center = v; + gst_geometric_transform_set_need_remap (gt); + } break; case PROP_RADIUS: - circle_geometric_transform->radius = g_value_get_double (value); + v = g_value_get_double (value); + if (v != cgt->radius) { + cgt->radius = v; + gst_geometric_transform_set_need_remap (gt); + } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } + GST_OBJECT_UNLOCK (cgt); } static void gst_circle_geometric_transform_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - GstCircleGeometricTransform *circle_geometric_transform; + GstCircleGeometricTransform *cgt; - circle_geometric_transform = GST_CIRCLE_GEOMETRIC_TRANSFORM_CAST (object); + cgt = GST_CIRCLE_GEOMETRIC_TRANSFORM_CAST (object); switch (prop_id) { case PROP_X_CENTER: - g_value_set_double (value, circle_geometric_transform->x_center); + g_value_set_double (value, cgt->x_center); break; case PROP_Y_CENTER: - g_value_set_double (value, circle_geometric_transform->y_center); + g_value_set_double (value, cgt->y_center); break; case PROP_RADIUS: - g_value_set_double (value, circle_geometric_transform->radius); + g_value_set_double (value, cgt->radius); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -170,16 +187,17 @@ gst_circle_geometric_transform_class_init (GstCircleGeometricTransformClass * g_param_spec_double ("x-center", "x center", "X axis center of the circle_geometric_transform effect", 0.0, 1.0, DEFAULT_X_CENTER, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_Y_CENTER, g_param_spec_double ("y-center", "y center", "Y axis center of the circle_geometric_transform effect", 0.0, 1.0, DEFAULT_Y_CENTER, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_RADIUS, g_param_spec_double ("radius", "radius", "radius of the circle_geometric_transform effect", 0.0, G_MAXDOUBLE, - DEFAULT_RADIUS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + DEFAULT_RADIUS, + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gstgt_class->prepare_func = circle_geometric_transform_precalc; } diff --git a/gst/geometrictransform/gstdiffuse.c b/gst/geometrictransform/gstdiffuse.c index 6d988b6d11..5f43a2b17f 100644 --- a/gst/geometrictransform/gstdiffuse.c +++ b/gst/geometrictransform/gstdiffuse.c @@ -76,17 +76,26 @@ gst_diffuse_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstDiffuse *diffuse; + GstGeometricTransform *gt; + gdouble v; + gt = GST_GEOMETRIC_TRANSFORM_CAST (object); diffuse = GST_DIFFUSE_CAST (object); + GST_OBJECT_LOCK (diffuse); switch (prop_id) { case PROP_SCALE: - diffuse->scale = g_value_get_double (value); + v = g_value_get_double (value); + if (v != diffuse->scale) { + diffuse->scale = v; + gst_geometric_transform_set_need_remap (gt); + } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } + GST_OBJECT_UNLOCK (diffuse); } static void @@ -193,7 +202,7 @@ gst_diffuse_class_init (GstDiffuseClass * klass) g_param_spec_double ("scale", "scale", "Scale of the texture", 1, G_MAXDOUBLE, DEFAULT_SCALE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gstgt_class->prepare_func = diffuse_prepare; gstgt_class->map_func = diffuse_map; diff --git a/gst/geometrictransform/gstgeometrictransform.c b/gst/geometrictransform/gstgeometrictransform.c index 909d9a04f7..2524758be0 100644 --- a/gst/geometrictransform/gstgeometrictransform.c +++ b/gst/geometrictransform/gstgeometrictransform.c @@ -23,6 +23,7 @@ #include "gstgeometrictransform.h" #include "geometricmath.h" +#include #include GST_DEBUG_CATEGORY_STATIC (geometric_transform_debug); @@ -102,6 +103,7 @@ gst_geometric_transform_off_edges_pixels_method_get_type (void) #define DEFAULT_OFF_EDGE_PIXELS GST_GT_OFF_EDGES_PIXELS_IGNORE +/* must be called with the object lock */ static gboolean gst_geometric_transform_generate_map (GstGeometricTransform * gt) { @@ -143,6 +145,8 @@ gst_geometric_transform_generate_map (GstGeometricTransform * gt) end: if (!ret) g_free (gt->map); + else + gt->needs_remap = FALSE; return ret; } @@ -169,14 +173,18 @@ gst_geometric_transform_set_caps (GstBaseTransform * btrans, GstCaps * incaps, gt->pixel_stride = gst_video_format_get_pixel_stride (gt->format, 0); /* regenerate the map */ + GST_OBJECT_LOCK (gt); if (old_width == 0 || old_height == 0 || gt->width != old_width || gt->height != old_height) { if (klass->prepare_func) - if (!klass->prepare_func (gt)) + if (!klass->prepare_func (gt)) { + GST_OBJECT_UNLOCK (gt); return FALSE; + } if (gt->precalc_map) gst_geometric_transform_generate_map (gt); } + GST_OBJECT_UNLOCK (gt); } return ret; } @@ -224,6 +232,23 @@ gst_geometric_transform_do_map (GstGeometricTransform * gt, GstBuffer * inbuf, } } +static void +gst_geometric_transform_before_transform (GstBaseTransform * trans, + GstBuffer * outbuf) +{ + GstGeometricTransform *gt = GST_GEOMETRIC_TRANSFORM (trans); + GstClockTime timestamp, stream_time; + + timestamp = GST_BUFFER_TIMESTAMP (outbuf); + stream_time = + gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME, timestamp); + + GST_DEBUG_OBJECT (gt, "sync to %" GST_TIME_FORMAT, GST_TIME_ARGS (timestamp)); + + if (GST_CLOCK_TIME_IS_VALID (stream_time)) + gst_object_sync_values (G_OBJECT (gt), stream_time); +} + static GstFlowReturn gst_geometric_transform_transform (GstBaseTransform * trans, GstBuffer * buf, GstBuffer * outbuf) @@ -239,7 +264,16 @@ gst_geometric_transform_transform (GstBaseTransform * trans, GstBuffer * buf, memset (GST_BUFFER_DATA (outbuf), 0, GST_BUFFER_SIZE (outbuf)); + GST_OBJECT_LOCK (gt); if (gt->precalc_map) { + if (gt->needs_remap) { + if (klass->prepare_func) + if (!klass->prepare_func (gt)) { + GST_OBJECT_UNLOCK (gt); + return FALSE; + } + gst_geometric_transform_generate_map (gt); + } g_return_val_if_fail (gt->map, GST_FLOW_ERROR); ptr = gt->map; for (y = 0; y < gt->height; y++) { @@ -258,11 +292,14 @@ gst_geometric_transform_transform (GstBaseTransform * trans, GstBuffer * buf, gst_geometric_transform_do_map (gt, buf, outbuf, x, y, in_x, in_y); } else { GST_WARNING_OBJECT (gt, "Failed to do mapping for %d %d", x, y); - return GST_FLOW_ERROR; + ret = GST_FLOW_ERROR; + goto end; } } } } +end: + GST_OBJECT_UNLOCK (gt); return ret; } @@ -276,7 +313,9 @@ gst_geometric_transform_set_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_OFF_EDGE_PIXELS: + GST_OBJECT_LOCK (gt); gt->off_edge_pixels = g_value_get_enum (value); + GST_OBJECT_UNLOCK (gt); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -344,12 +383,14 @@ gst_geometric_transform_class_init (gpointer klass, gpointer class_data) trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_geometric_transform_set_caps); trans_class->transform = GST_DEBUG_FUNCPTR (gst_geometric_transform_transform); + trans_class->before_transform = + GST_DEBUG_FUNCPTR (gst_geometric_transform_before_transform); g_object_class_install_property (obj_class, PROP_OFF_EDGE_PIXELS, g_param_spec_enum ("off-edge-pixels", "Off edge pixels", "What to do with off edge pixels", GST_GT_OFF_EDGES_PIXELS_METHOD_TYPE, DEFAULT_OFF_EDGE_PIXELS, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static void @@ -359,6 +400,7 @@ gst_geometric_transform_init (GTypeInstance * instance, gpointer g_class) gt->off_edge_pixels = DEFAULT_OFF_EDGE_PIXELS; gt->precalc_map = TRUE; + gt->needs_remap = TRUE; } GType @@ -388,3 +430,12 @@ gst_geometric_transform_get_type (void) } return geometric_transform_type; } + +/* + * Must be called with the object lock + */ +void +gst_geometric_transform_set_need_remap (GstGeometricTransform * gt) +{ + gt->needs_remap = TRUE; +} diff --git a/gst/geometrictransform/gstgeometrictransform.h b/gst/geometrictransform/gstgeometrictransform.h index c92c408f9d..09c026b3ed 100644 --- a/gst/geometrictransform/gstgeometrictransform.h +++ b/gst/geometrictransform/gstgeometrictransform.h @@ -29,6 +29,7 @@ G_BEGIN_DECLS (gst_geometric_transform_get_type()) #define GST_GEOMETRIC_TRANSFORM(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GEOMETRIC_TRANSFORM,GstGeometricTransform)) +#define GST_GEOMETRIC_TRANSFORM_CAST(obj) ((GstGeometricTransform *)(obj)) #define GST_GEOMETRIC_TRANSFORM_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GEOMETRIC_TRANSFORM,GstGeometricTransformClass)) #define GST_IS_GEOMETRIC_TRANSFORM(obj) \ @@ -70,6 +71,8 @@ typedef gboolean (*GstGeometricTransformMapFunc) (GstGeometricTransform * gt, * * Called right before starting to calculate the mapping so that * instances might precalculate some values. + * + * Called with the object lock */ typedef gboolean (*GstGeometricTransformPrepareFunc) ( GstGeometricTransform * gt); @@ -92,6 +95,7 @@ struct _GstGeometricTransform { * pixel mapping table. Like 'diffuse' that uses random values for each pic. */ gboolean precalc_map; + gboolean needs_remap; /* properties */ gint off_edge_pixels; @@ -108,6 +112,8 @@ struct _GstGeometricTransformClass { GType gst_geometric_transform_get_type (void); +void gst_geometric_transform_set_need_remap (GstGeometricTransform * gt); + G_END_DECLS #endif /* __GST_GEOMETRIC_TRANSFORM_H__ */ diff --git a/gst/geometrictransform/gstkaleidoscope.c b/gst/geometrictransform/gstkaleidoscope.c index 15c8eb1800..ecc369013c 100644 --- a/gst/geometrictransform/gstkaleidoscope.c +++ b/gst/geometrictransform/gstkaleidoscope.c @@ -81,23 +81,41 @@ gst_kaleidoscope_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstKaleidoscope *kaleidoscope; + GstGeometricTransform *gt; + gdouble v; + gint s; + gt = GST_GEOMETRIC_TRANSFORM_CAST (object); kaleidoscope = GST_KALEIDOSCOPE_CAST (object); + GST_OBJECT_LOCK (gt); switch (prop_id) { case PROP_ANGLE: - kaleidoscope->angle = g_value_get_double (value); + v = g_value_get_double (value); + if (v != kaleidoscope->angle) { + kaleidoscope->angle = v; + gst_geometric_transform_set_need_remap (gt); + } break; case PROP_ANGLE2: - kaleidoscope->angle2 = g_value_get_double (value); + v = g_value_get_double (value); + if (v != kaleidoscope->angle2) { + kaleidoscope->angle2 = v; + gst_geometric_transform_set_need_remap (gt); + } break; case PROP_SIDES: - kaleidoscope->sides = g_value_get_int (value); + s = g_value_get_int (value); + if (s != kaleidoscope->sides) { + kaleidoscope->sides = s; + gst_geometric_transform_set_need_remap (gt); + } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } + GST_OBJECT_UNLOCK (gt); } static void @@ -200,16 +218,16 @@ gst_kaleidoscope_class_init (GstKaleidoscopeClass * klass) g_param_spec_double ("angle", "angle", "primary angle in radians of the kaleidoscope effect", -G_MAXDOUBLE, G_MAXDOUBLE, DEFAULT_ANGLE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_ANGLE2, g_param_spec_double ("angle2", "angle2", "secondary angle in radians of the kaleidoscope effect", -G_MAXDOUBLE, G_MAXDOUBLE, DEFAULT_ANGLE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_SIDES, g_param_spec_int ("sides", "sides", "Number of sides of the kaleidoscope", 2, G_MAXINT, DEFAULT_SIDES, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gstgt_class->map_func = kaleidoscope_map; } diff --git a/gst/geometrictransform/gstmarble.c b/gst/geometrictransform/gstmarble.c index fd6e31ca27..2c2ab64ae1 100644 --- a/gst/geometrictransform/gstmarble.c +++ b/gst/geometrictransform/gstmarble.c @@ -82,26 +82,47 @@ gst_marble_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstMarble *marble; + GstGeometricTransform *gt; + gdouble v; + gt = GST_GEOMETRIC_TRANSFORM_CAST (object); marble = GST_MARBLE_CAST (object); + GST_OBJECT_LOCK (gt); switch (prop_id) { case PROP_XSCALE: - marble->xscale = g_value_get_double (value); + v = g_value_get_double (value); + if (v != marble->xscale) { + marble->xscale = v; + gst_geometric_transform_set_need_remap (gt); + } break; case PROP_YSCALE: - marble->yscale = g_value_get_double (value); + v = g_value_get_double (value); + if (v != marble->yscale) { + marble->yscale = v; + gst_geometric_transform_set_need_remap (gt); + } break; case PROP_AMOUNT: - marble->amount = g_value_get_double (value); + v = g_value_get_double (value); + if (v != marble->amount) { + marble->amount = v; + gst_geometric_transform_set_need_remap (gt); + } break; case PROP_TURBULENCE: - marble->turbulence = g_value_get_double (value); + v = g_value_get_double (value); + if (v != marble->turbulence) { + marble->turbulence = v; + gst_geometric_transform_set_need_remap (gt); + } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } + GST_OBJECT_UNLOCK (gt); } static void @@ -222,22 +243,22 @@ gst_marble_class_init (GstMarbleClass * klass) g_param_spec_double ("x-scale", "x-scale", "X scale of the texture", 0, G_MAXDOUBLE, DEFAULT_XSCALE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_YSCALE, g_param_spec_double ("y-scale", "y-scale", "Y scale of the texture", 0, G_MAXDOUBLE, DEFAULT_YSCALE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_AMOUNT, g_param_spec_double ("amount", "amount", "Amount of effect", 0.0, 1.0, DEFAULT_AMOUNT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_YSCALE, g_param_spec_double ("turbulence", "turbulence", "Turbulence of the effect", 0.0, 1.0, DEFAULT_TURBULENCE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gstgt_class->prepare_func = marble_prepare; gstgt_class->map_func = marble_map; diff --git a/gst/geometrictransform/gstpinch.c b/gst/geometrictransform/gstpinch.c index 39dbf63a82..9a6ae9ca53 100644 --- a/gst/geometrictransform/gstpinch.c +++ b/gst/geometrictransform/gstpinch.c @@ -76,17 +76,26 @@ gst_pinch_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstPinch *pinch; + GstGeometricTransform *gt; + gdouble v; + gt = GST_GEOMETRIC_TRANSFORM_CAST (object); pinch = GST_PINCH_CAST (object); + GST_OBJECT_LOCK (gt); switch (prop_id) { case PROP_INTENSITY: - pinch->intensity = g_value_get_double (value); + v = g_value_get_double (value); + if (v != pinch->intensity) { + pinch->intensity = v; + gst_geometric_transform_set_need_remap (gt); + } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } + GST_OBJECT_UNLOCK (gt); } static void @@ -189,7 +198,7 @@ gst_pinch_class_init (GstPinchClass * klass) g_param_spec_double ("intensity", "intensity", "intensity of the pinch effect", -1.0, 1.0, DEFAULT_INTENSITY, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gstgt_class->map_func = pinch_map; } diff --git a/gst/geometrictransform/gstsphere.c b/gst/geometrictransform/gstsphere.c index 0ada5dda6a..b398e6d1d1 100644 --- a/gst/geometrictransform/gstsphere.c +++ b/gst/geometrictransform/gstsphere.c @@ -76,17 +76,26 @@ gst_sphere_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstSphere *sphere; + GstGeometricTransform *gt; + gdouble v; + gt = GST_GEOMETRIC_TRANSFORM_CAST (object); sphere = GST_SPHERE_CAST (object); + GST_OBJECT_LOCK (gt); switch (prop_id) { case PROP_REFRACTION: - sphere->refraction = g_value_get_double (value); + v = g_value_get_double (value); + if (v != sphere->refraction) { + sphere->refraction = v; + gst_geometric_transform_set_need_remap (gt); + } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } + GST_OBJECT_UNLOCK (gt); } static void @@ -200,7 +209,7 @@ gst_sphere_class_init (GstSphereClass * klass) g_param_spec_double ("refraction", "refraction", "refraction index", -G_MAXDOUBLE, G_MAXDOUBLE, DEFAULT_REFRACTION, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gstgt_class->map_func = sphere_map; } diff --git a/gst/geometrictransform/gsttwirl.c b/gst/geometrictransform/gsttwirl.c index 1e1b989a1c..51302d4132 100644 --- a/gst/geometrictransform/gsttwirl.c +++ b/gst/geometrictransform/gsttwirl.c @@ -76,17 +76,26 @@ gst_twirl_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstTwirl *twirl; + GstGeometricTransform *gt; + gdouble v; + gt = GST_GEOMETRIC_TRANSFORM_CAST (object); twirl = GST_TWIRL_CAST (object); + GST_OBJECT_LOCK (gt); switch (prop_id) { case PROP_ANGLE: - twirl->angle = g_value_get_double (value); + v = g_value_get_double (value); + if (v != twirl->angle) { + twirl->angle = v; + gst_geometric_transform_set_need_remap (gt); + } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } + GST_OBJECT_UNLOCK (gt); } static void @@ -178,7 +187,7 @@ gst_twirl_class_init (GstTwirlClass * klass) "This is the angle in radians by which pixels at the " "nearest edge of the image will move", -G_MAXDOUBLE, G_MAXDOUBLE, DEFAULT_ANGLE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gstgt_class->map_func = twirl_map; } diff --git a/gst/geometrictransform/gstwaterripple.c b/gst/geometrictransform/gstwaterripple.c index 81eb08b4ee..d66d983405 100644 --- a/gst/geometrictransform/gstwaterripple.c +++ b/gst/geometrictransform/gstwaterripple.c @@ -80,23 +80,40 @@ gst_water_ripple_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstWaterRipple *water_ripple; + GstGeometricTransform *gt; + gdouble v; + gt = GST_GEOMETRIC_TRANSFORM_CAST (object); water_ripple = GST_WATER_RIPPLE_CAST (object); + GST_OBJECT_LOCK (gt); switch (prop_id) { case PROP_AMPLITUDE: - water_ripple->amplitude = g_value_get_double (value); + v = g_value_get_double (value); + if (v != water_ripple->amplitude) { + water_ripple->amplitude = v; + gst_geometric_transform_set_need_remap (gt); + } break; case PROP_PHASE: - water_ripple->phase = g_value_get_double (value); + v = g_value_get_double (value); + if (v != water_ripple->phase) { + water_ripple->phase = v; + gst_geometric_transform_set_need_remap (gt); + } break; case PROP_WAVELENGTH: - water_ripple->wavelength = g_value_get_double (value); + v = g_value_get_double (value); + if (v != water_ripple->wavelength) { + water_ripple->wavelength = v; + gst_geometric_transform_set_need_remap (gt); + } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } + GST_OBJECT_UNLOCK (gt); } static void @@ -200,15 +217,15 @@ gst_water_ripple_class_init (GstWaterRippleClass * klass) g_object_class_install_property (gobject_class, PROP_AMPLITUDE, g_param_spec_double ("amplitude", "amplitude", "amplitude", -G_MAXDOUBLE, G_MAXDOUBLE, DEFAULT_AMPLITUDE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_PHASE, g_param_spec_double ("phase", "phase", "phase", -G_MAXDOUBLE, G_MAXDOUBLE, DEFAULT_PHASE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_WAVELENGTH, g_param_spec_double ("wavelength", "wavelength", "wavelength", -G_MAXDOUBLE, G_MAXDOUBLE, DEFAULT_WAVELENGTH, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gstgt_class->map_func = water_ripple_map; }