effectv: Use controller where possible, optimize a bit and make properties threadsafe
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Sun, 28 Feb 2010 14:47:50 +0000 (15:47 +0100)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 9 Mar 2010 21:03:18 +0000 (21:03 +0000)
12 files changed:
gst/effectv/gstaging.c
gst/effectv/gstdice.c
gst/effectv/gstedge.c
gst/effectv/gstop.c
gst/effectv/gstquark.c
gst/effectv/gstradioac.c
gst/effectv/gstrev.c
gst/effectv/gstripple.c
gst/effectv/gstshagadelic.c
gst/effectv/gststreak.c
gst/effectv/gstvertigo.c
gst/effectv/gstwarp.c

index 5facd31..8bd2a85 100644 (file)
@@ -101,10 +101,12 @@ gst_agingtv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
   structure = gst_caps_get_structure (incaps, 0);
 
+  GST_OBJECT_LOCK (filter);
   if (gst_structure_get_int (structure, "width", &filter->width) &&
       gst_structure_get_int (structure, "height", &filter->height)) {
     ret = TRUE;
   }
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -262,6 +264,7 @@ gst_agingtv_get_property (GObject * object, guint prop_id,
 {
   GstAgingTV *agingtv = GST_AGINGTV (object);
 
+  GST_OBJECT_LOCK (agingtv);
   switch (prop_id) {
     case PROP_SCRATCH_LINES:
       g_value_set_uint (value, agingtv->scratch_lines);
@@ -278,6 +281,7 @@ gst_agingtv_get_property (GObject * object, guint prop_id,
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   }
+  GST_OBJECT_UNLOCK (agingtv);
 }
 
 static void
@@ -323,12 +327,10 @@ gst_agingtv_transform (GstBaseTransform * trans, GstBuffer * in,
     GstBuffer * out)
 {
   GstAgingTV *agingtv = GST_AGINGTV (trans);
-  gint width = agingtv->width;
-  gint height = agingtv->height;
-  gint video_size = width * height;
+  gint width, height, video_size;
   guint32 *src = (guint32 *) GST_BUFFER_DATA (in);
   guint32 *dest = (guint32 *) GST_BUFFER_DATA (out);
-  gint area_scale = width * height / 64 / 480;
+  gint area_scale;
   GstFlowReturn ret = GST_FLOW_OK;
   GstClockTime timestamp, stream_time;
 
@@ -342,6 +344,12 @@ gst_agingtv_transform (GstBaseTransform * trans, GstBuffer * in,
   if (GST_CLOCK_TIME_IS_VALID (stream_time))
     gst_object_sync_values (G_OBJECT (agingtv), stream_time);
 
+  GST_OBJECT_LOCK (agingtv);
+  width = agingtv->width;
+  height = agingtv->height;
+  video_size = width * height;
+
+  area_scale = width * height / 64 / 480;
   if (area_scale <= 0)
     area_scale = 1;
 
@@ -355,6 +363,7 @@ gst_agingtv_transform (GstBaseTransform * trans, GstBuffer * in,
     pits (dest, width, height, area_scale, &agingtv->pits_interval);
   if (area_scale > 1 && agingtv->dusts)
     dusts (dest, width, height, &agingtv->dust_interval, area_scale);
+  GST_OBJECT_UNLOCK (agingtv);
 
   return ret;
 }
@@ -416,7 +425,4 @@ gst_agingtv_init (GstAgingTV * agingtv, GstAgingTVClass * klass)
   agingtv->color_aging = DEFAULT_COLOR_AGING;
   agingtv->pits = DEFAULT_PITS;
   agingtv->dusts = DEFAULT_DUSTS;
-
-  gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (agingtv));
-  gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SRC_PAD (agingtv));
 }
index 5d73b7a..bedabe0 100644 (file)
@@ -104,6 +104,7 @@ gst_dicetv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
   structure = gst_caps_get_structure (incaps, 0);
 
+  GST_OBJECT_LOCK (filter);
   if (gst_structure_get_int (structure, "width", &filter->width) &&
       gst_structure_get_int (structure, "height", &filter->height)) {
     g_free (filter->dicemap);
@@ -111,6 +112,7 @@ gst_dicetv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
     gst_dicetv_create_map (filter);
     ret = TRUE;
   }
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -122,8 +124,10 @@ gst_dicetv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
   guint32 *src, *dest;
   gint i, map_x, map_y, map_i, base, dx, dy, di;
   gint video_width, g_cube_bits, g_cube_size;
+  gint g_map_height, g_map_width;
   GstFlowReturn ret = GST_FLOW_OK;
   GstClockTime timestamp, stream_time;
+  const guint8 *dicemap;
 
   src = (guint32 *) GST_BUFFER_DATA (in);
   dest = (guint32 *) GST_BUFFER_DATA (out);
@@ -138,16 +142,21 @@ gst_dicetv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
   if (GST_CLOCK_TIME_IS_VALID (stream_time))
     gst_object_sync_values (G_OBJECT (filter), stream_time);
 
+  GST_OBJECT_LOCK (filter);
   video_width = filter->width;
   g_cube_bits = filter->g_cube_bits;
   g_cube_size = filter->g_cube_size;
+  g_map_height = filter->g_map_height;
+  g_map_width = filter->g_map_width;
+
+  dicemap = filter->dicemap;
 
   map_i = 0;
-  for (map_y = 0; map_y < filter->g_map_height; map_y++) {
-    for (map_x = 0; map_x < filter->g_map_width; map_x++) {
+  for (map_y = 0; map_y < g_map_height; map_y++) {
+    for (map_x = 0; map_x < g_map_width; map_x++) {
       base = (map_y << g_cube_bits) * video_width + (map_x << g_cube_bits);
 
-      switch (filter->dicemap[map_i]) {
+      switch (dicemap[map_i]) {
         case DICE_UP:
           for (dy = 0; dy < g_cube_size; dy++) {
             i = base + dy * video_width;
@@ -196,6 +205,7 @@ gst_dicetv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
       map_i++;
     }
   }
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -231,8 +241,10 @@ gst_dicetv_set_property (GObject * object, guint prop_id, const GValue * value,
 
   switch (prop_id) {
     case PROP_CUBE_BITS:
+      GST_OBJECT_LOCK (filter);
       filter->g_cube_bits = g_value_get_int (value);
       gst_dicetv_create_map (filter);
+      GST_OBJECT_UNLOCK (filter);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -310,7 +322,4 @@ gst_dicetv_init (GstDiceTV * filter, GstDiceTVClass * klass)
   filter->g_cube_size = 0;
   filter->g_map_height = 0;
   filter->g_map_width = 0;
-
-  gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (filter));
-  gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SRC_PAD (filter));
 }
index 00e4629..db109bf 100644 (file)
@@ -80,6 +80,7 @@ gst_edgetv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
   structure = gst_caps_get_structure (incaps, 0);
 
+  GST_OBJECT_LOCK (edgetv);
   if (gst_structure_get_int (structure, "width", &edgetv->width) &&
       gst_structure_get_int (structure, "height", &edgetv->height)) {
     guint map_size;
@@ -94,6 +95,7 @@ gst_edgetv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
     edgetv->map = (guint32 *) g_malloc0 (map_size);
     ret = TRUE;
   }
+  GST_OBJECT_UNLOCK (edgetv);
 
   return ret;
 }
@@ -106,16 +108,26 @@ gst_edgetv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
   guint32 *src, *dest;
   guint32 p, q;
   guint32 v0, v1, v2, v3;
+  gint height, width, map_height, map_width;
+  gint video_width_margin;
+  guint32 *map;
   GstFlowReturn ret = GST_FLOW_OK;
 
   src = (guint32 *) GST_BUFFER_DATA (in);
   dest = (guint32 *) GST_BUFFER_DATA (out);
 
-  src += filter->width * 4 + 4;
-  dest += filter->width * 4 + 4;
-
-  for (y = 1; y < filter->map_height - 1; y++) {
-    for (x = 1; x < filter->map_width - 1; x++) {
+  GST_OBJECT_LOCK (filter);
+  map = filter->map;
+  height = filter->height;
+  width = filter->width;
+  map_height = filter->map_height;
+  map_width = filter->map_width;
+  video_width_margin = filter->video_width_margin;
+  src += width * 4 + 4;
+  dest += width * 4 + 4;
+
+  for (y = 1; y < map_height - 1; y++) {
+    for (x = 1; x < map_width - 1; x++) {
       p = *src;
       q = *(src - 4);
 
@@ -138,7 +150,7 @@ gst_edgetv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
       v2 = (r << 17) | (g << 9) | b;
 
       /* difference between the current pixel and upper neighbor. */
-      q = *(src - filter->width * 4);
+      q = *(src - width * 4);
       r = ((p & 0xff0000) - (q & 0xff0000)) >> 16;
       g = ((p & 0xff00) - (q & 0xff00)) >> 8;
       b = (p & 0xff) - (q & 0xff);
@@ -156,10 +168,10 @@ gst_edgetv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
         b = 255;
       v3 = (r << 17) | (g << 9) | b;
 
-      v0 = filter->map[(y - 1) * filter->map_width * 2 + x * 2];
-      v1 = filter->map[y * filter->map_width * 2 + (x - 1) * 2 + 1];
-      filter->map[y * filter->map_width * 2 + x * 2] = v2;
-      filter->map[y * filter->map_width * 2 + x * 2 + 1] = v3;
+      v0 = map[(y - 1) * map_width * 2 + x * 2];
+      v1 = map[y * map_width * 2 + (x - 1) * 2 + 1];
+      map[y * map_width * 2 + x * 2] = v2;
+      map[y * map_width * 2 + x * 2 + 1] = v3;
       r = v0 + v1;
       g = r & 0x01010100;
       dest[0] = r | (g - (g >> 8));
@@ -170,23 +182,24 @@ gst_edgetv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
       dest[3] = v3;
       r = v2 + v1;
       g = r & 0x01010100;
-      dest[filter->width] = r | (g - (g >> 8));
+      dest[width] = r | (g - (g >> 8));
       r = v2 + v3;
       g = r & 0x01010100;
-      dest[filter->width + 1] = r | (g - (g >> 8));
-      dest[filter->width + 2] = v3;
-      dest[filter->width + 3] = v3;
-      dest[filter->width * 2] = v2;
-      dest[filter->width * 2 + 1] = v2;
-      dest[filter->width * 3] = v2;
-      dest[filter->width * 3 + 1] = v2;
+      dest[width + 1] = r | (g - (g >> 8));
+      dest[width + 2] = v3;
+      dest[width + 3] = v3;
+      dest[width * 2] = v2;
+      dest[width * 2 + 1] = v2;
+      dest[width * 3] = v2;
+      dest[width * 3 + 1] = v2;
 
       src += 4;
       dest += 4;
     }
-    src += filter->width * 3 + 8 + filter->video_width_margin;
-    dest += filter->width * 3 + 8 + filter->video_width_margin;
+    src += width * 3 + 8 + video_width_margin;
+    dest += width * 3 + 8 + video_width_margin;
   }
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
index b371ba7..d9e35df 100644 (file)
@@ -206,8 +206,9 @@ gst_optv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
   GstFlowReturn ret = GST_FLOW_OK;
   gint8 *p;
   guint8 *diff;
-  gint x, y;
+  gint x, y, width, height;
   GstClockTime timestamp, stream_time;
+  guint8 phase;
 
   timestamp = GST_BUFFER_TIMESTAMP (in);
   stream_time =
@@ -225,6 +226,7 @@ gst_optv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
   if (G_UNLIKELY (filter->opmap[0] == NULL))
     return GST_FLOW_NOT_NEGOTIATED;
 
+  GST_OBJECT_LOCK (filter);
   switch (filter->mode) {
     default:
     case 0:
@@ -245,13 +247,17 @@ gst_optv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
 
   diff = filter->diff;
   image_y_over (src, diff, filter->threshold, filter->width * filter->height);
+  height = filter->height;
+  width = filter->width;
+  phase = filter->phase;
 
-  for (y = 0; y < filter->height; y++) {
-    for (x = 0; x < filter->width; x++) {
-      *dest++ = palette[(((guint8) (*p + filter->phase)) ^ *diff++) & 255];
+  for (y = 0; y < height; y++) {
+    for (x = 0; x < width; x++) {
+      *dest++ = palette[(((guint8) (*p + phase)) ^ *diff++) & 255];
       p++;
     }
   }
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -266,6 +272,7 @@ gst_optv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
   structure = gst_caps_get_structure (incaps, 0);
 
+  GST_OBJECT_LOCK (filter);
   if (gst_structure_get_int (structure, "width", &filter->width) &&
       gst_structure_get_int (structure, "height", &filter->height)) {
     gint i;
@@ -283,6 +290,7 @@ gst_optv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
     ret = TRUE;
   }
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -325,6 +333,7 @@ gst_optv_set_property (GObject * object, guint prop_id, const GValue * value,
 {
   GstOpTV *filter = GST_OPTV (object);
 
+  GST_OBJECT_LOCK (filter);
   switch (prop_id) {
     case PROP_MODE:
       filter->mode = g_value_get_enum (value);
@@ -339,6 +348,7 @@ gst_optv_set_property (GObject * object, guint prop_id, const GValue * value,
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
+  GST_OBJECT_UNLOCK (filter);
 }
 
 static void
index 29bed2b..3b307f2 100644 (file)
@@ -48,6 +48,7 @@
 #include "gstquark.h"
 #include "gsteffectv.h"
 
+#include <gst/controller/gstcontroller.h>
 #include <gst/video/video.h>
 
 /* number of frames of time-buffer. It should be as a configurable paramater */
@@ -91,12 +92,14 @@ gst_quarktv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
   structure = gst_caps_get_structure (incaps, 0);
 
+  GST_OBJECT_LOCK (filter);
   if (gst_structure_get_int (structure, "width", &filter->width) &&
       gst_structure_get_int (structure, "height", &filter->height)) {
     gst_quarktv_planetable_clear (filter);
     filter->area = filter->width * filter->height;
     ret = TRUE;
   }
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -109,27 +112,41 @@ gst_quarktv_transform (GstBaseTransform * trans, GstBuffer * in,
   gint area;
   guint32 *src, *dest;
   GstFlowReturn ret = GST_FLOW_OK;
+  GstClockTime timestamp;
+  GstBuffer **planetable;
+  gint planes, current_plane;
 
-  area = filter->area;
-  src = (guint32 *) GST_BUFFER_DATA (in);
-  dest = (guint32 *) GST_BUFFER_DATA (out);
+  timestamp = GST_BUFFER_TIMESTAMP (in);
+  timestamp =
+      gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME, timestamp);
+
+  GST_DEBUG_OBJECT (filter, "sync to %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (timestamp));
+
+  if (GST_CLOCK_TIME_IS_VALID (timestamp))
+    gst_object_sync_values (G_OBJECT (filter), timestamp);
 
   if (G_UNLIKELY (filter->planetable == NULL))
     return GST_FLOW_WRONG_STATE;
 
-  if (filter->planetable[filter->current_plane])
-    gst_buffer_unref (filter->planetable[filter->current_plane]);
+  GST_OBJECT_LOCK (filter);
+  area = filter->area;
+  src = (guint32 *) GST_BUFFER_DATA (in);
+  dest = (guint32 *) GST_BUFFER_DATA (out);
+  planetable = filter->planetable;
+  planes = filter->planes;
+  current_plane = filter->current_plane;
 
-  filter->planetable[filter->current_plane] = gst_buffer_ref (in);
+  if (planetable[current_plane])
+    gst_buffer_unref (planetable[current_plane]);
+  planetable[current_plane] = gst_buffer_ref (in);
 
   /* For each pixel */
   while (--area) {
     GstBuffer *rand;
 
     /* pick a random buffer */
-    rand =
-        filter->planetable[(filter->current_plane +
-            (fastrand () >> 24)) % filter->planes];
+    rand = planetable[(current_plane + (fastrand () >> 24)) % planes];
 
     /* Copy the pixel from the random buffer to dest */
     dest[area] =
@@ -138,7 +155,8 @@ gst_quarktv_transform (GstBaseTransform * trans, GstBuffer * in,
 
   filter->current_plane--;
   if (filter->current_plane < 0)
-    filter->current_plane = filter->planes - 1;
+    filter->current_plane = planes - 1;
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -194,6 +212,7 @@ gst_quarktv_set_property (GObject * object, guint prop_id, const GValue * value,
 {
   GstQuarkTV *filter = GST_QUARKTV (object);
 
+  GST_OBJECT_LOCK (filter);
   switch (prop_id) {
     case PROP_PLANES:
     {
@@ -227,6 +246,7 @@ gst_quarktv_set_property (GObject * object, guint prop_id, const GValue * value,
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
+  GST_OBJECT_UNLOCK (filter);
 }
 
 static void
@@ -274,7 +294,7 @@ gst_quarktv_class_init (GstQuarkTVClass * klass)
   g_object_class_install_property (gobject_class, PROP_PLANES,
       g_param_spec_int ("planes", "Planes",
           "Number of planes", 0, 64, PLANES,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
 
   trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_quarktv_set_caps);
   trans_class->transform = GST_DEBUG_FUNCPTR (gst_quarktv_transform);
index 7d954a8..85b4ecc 100644 (file)
@@ -327,8 +327,6 @@ gst_radioactv_transform (GstBaseTransform * trans, GstBuffer * in,
   guint8 *diff, *p;
   guint32 *palette;
 
-  palette = &palettes[COLORS * filter->color];
-
   timestamp = GST_BUFFER_TIMESTAMP (in);
   stream_time =
       gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME, timestamp);
@@ -342,6 +340,8 @@ gst_radioactv_transform (GstBaseTransform * trans, GstBuffer * in,
   src = (guint32 *) GST_BUFFER_DATA (in);
   dest = (guint32 *) GST_BUFFER_DATA (out);
 
+  GST_OBJECT_LOCK (filter);
+  palette = &palettes[COLORS * filter->color];
   diff = filter->diff;
 
   if (filter->mode == 3 && filter->trigger)
@@ -395,6 +395,7 @@ gst_radioactv_transform (GstBaseTransform * trans, GstBuffer * in,
       filter->snaptime = filter->interval;
     }
   }
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -409,11 +410,12 @@ gst_radioactv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
   structure = gst_caps_get_structure (incaps, 0);
 
+  GST_OBJECT_LOCK (filter);
   if (gst_structure_get_int (structure, "width", &filter->width) &&
       gst_structure_get_int (structure, "height", &filter->height)) {
     filter->buf_width_blocks = filter->width / 32;
     if (filter->buf_width_blocks > 255)
-      return FALSE;
+      goto out;
 
     filter->buf_width = filter->buf_width_blocks * 32;
     filter->buf_height = filter->height;
@@ -450,6 +452,8 @@ gst_radioactv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
     ret = TRUE;
   }
+out:
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -502,6 +506,7 @@ gst_radioactv_set_property (GObject * object, guint prop_id,
 {
   GstRadioacTV *filter = GST_RADIOACTV (object);
 
+  GST_OBJECT_LOCK (filter);
   switch (prop_id) {
     case PROP_MODE:
       filter->mode = g_value_get_enum (value);
@@ -521,6 +526,7 @@ gst_radioactv_set_property (GObject * object, guint prop_id,
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
+  GST_OBJECT_UNLOCK (filter);
 }
 
 static void
index bd0bd9a..ad58a8e 100644 (file)
@@ -65,6 +65,7 @@
 #include "gstrev.h"
 
 #include <gst/video/video.h>
+#include <gst/controller/gstcontroller.h>
 
 #define THE_COLOR 0xffffffff
 
@@ -108,10 +109,12 @@ gst_revtv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
   structure = gst_caps_get_structure (incaps, 0);
 
+  GST_OBJECT_LOCK (filter);
   if (gst_structure_get_int (structure, "width", &filter->width) &&
       gst_structure_get_int (structure, "height", &filter->height)) {
     ret = TRUE;
   }
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -125,18 +128,34 @@ gst_revtv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
   guint32 *nsrc;
   gint y, x, R, G, B, yval;
   GstFlowReturn ret = GST_FLOW_OK;
+  gint linespace, vscale;
+  GstClockTime timestamp, stream_time;
+
+  timestamp = GST_BUFFER_TIMESTAMP (in);
+  stream_time =
+      gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME, timestamp);
+
+  GST_DEBUG_OBJECT (filter, "sync to %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (timestamp));
+
+  if (GST_CLOCK_TIME_IS_VALID (stream_time))
+    gst_object_sync_values (G_OBJECT (filter), stream_time);
 
   src = (guint32 *) GST_BUFFER_DATA (in);
   dest = (guint32 *) GST_BUFFER_DATA (out);
 
+  GST_OBJECT_LOCK (filter);
   width = filter->width;
   height = filter->height;
 
   /* Clear everything to black */
   memset (dest, 0, width * height * sizeof (guint32));
 
+  linespace = filter->linespace;
+  vscale = filter->vscale;
+
   /* draw the offset lines */
-  for (y = 0; y < height; y += filter->linespace) {
+  for (y = 0; y < height; y += linespace) {
     for (x = 0; x <= width; x++) {
       nsrc = src + (y * width) + x;
 
@@ -145,13 +164,14 @@ gst_revtv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
       G = ((*nsrc) & 0xff00) >> (8 - 2);
       B = (*nsrc) & 0xff;
 
-      yval = y - ((short) (R + G + B) / filter->vscale);
+      yval = y - ((short) (R + G + B) / vscale);
 
       if (yval > 0) {
         dest[x + (yval * width)] = THE_COLOR;
       }
     }
   }
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -162,6 +182,7 @@ gst_revtv_set_property (GObject * object, guint prop_id, const GValue * value,
 {
   GstRevTV *filter = GST_REVTV (object);
 
+  GST_OBJECT_LOCK (filter);
   switch (prop_id) {
     case PROP_DELAY:
       filter->vgrabtime = g_value_get_int (value);
@@ -173,8 +194,10 @@ gst_revtv_set_property (GObject * object, guint prop_id, const GValue * value,
       filter->vscale = g_value_get_int (value);
       break;
     default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
+  GST_OBJECT_UNLOCK (filter);
 }
 
 static void
@@ -226,13 +249,15 @@ gst_revtv_class_init (GstRevTVClass * klass)
 
   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DELAY,
       g_param_spec_int ("delay", "Delay", "Delay in frames between updates",
-          1, 100, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+          1, 100, 1,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LINESPACE,
-      g_param_spec_int ("linespace", "Linespace", "Control line spacing",
-          1, 100, 6, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+      g_param_spec_int ("linespace", "Linespace", "Control line spacing", 1,
+          100, 6,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_GAIN,
-      g_param_spec_int ("gain", "Gain", "Control gain",
-          1, 200, 50, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+      g_param_spec_int ("gain", "Gain", "Control gain", 1, 200, 50,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
 
   trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_revtv_set_caps);
   trans_class->transform = GST_DEBUG_FUNCPTR (gst_revtv_transform);
index 75e3981..e002ad1 100644 (file)
@@ -53,6 +53,7 @@
 #include "gsteffectv.h"
 
 #include <gst/video/video.h>
+#include <gst/controller/gstcontroller.h>
 
 #define DEFAULT_MODE 0
 
@@ -316,10 +317,22 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in,
   gint width, height;
   gint *p, *q, *r;
   gint8 *vp;
+  GstClockTime timestamp, stream_time;
+
+  timestamp = GST_BUFFER_TIMESTAMP (in);
+  stream_time =
+      gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME, timestamp);
+
+  GST_DEBUG_OBJECT (filter, "sync to %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (timestamp));
+
+  if (GST_CLOCK_TIME_IS_VALID (stream_time))
+    gst_object_sync_values (G_OBJECT (filter), stream_time);
 
   src = (guint32 *) GST_BUFFER_DATA (in);
   dest = (guint32 *) GST_BUFFER_DATA (out);
 
+  GST_OBJECT_LOCK (filter);
   /* impact from the motion or rain drop */
   if (filter->mode)
     raindrop (filter);
@@ -433,6 +446,7 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in,
     dest += filter->width;
     vp += 2;
   }
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -447,6 +461,7 @@ gst_rippletv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
   structure = gst_caps_get_structure (incaps, 0);
 
+  GST_OBJECT_LOCK (filter);
   if (gst_structure_get_int (structure, "width", &filter->width) &&
       gst_structure_get_int (structure, "height", &filter->height)) {
 
@@ -475,6 +490,7 @@ gst_rippletv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
     ret = TRUE;
   }
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -527,6 +543,7 @@ gst_rippletv_set_property (GObject * object, guint prop_id,
 {
   GstRippleTV *filter = GST_RIPPLETV (object);
 
+  GST_OBJECT_LOCK (filter);
   switch (prop_id) {
     case PROP_RESET:{
       memset (filter->map, 0,
@@ -540,6 +557,7 @@ gst_rippletv_set_property (GObject * object, guint prop_id,
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
+  GST_OBJECT_UNLOCK (filter);
 }
 
 static void
@@ -589,12 +607,12 @@ gst_rippletv_class_init (GstRippleTVClass * klass)
   g_object_class_install_property (gobject_class, PROP_RESET,
       g_param_spec_boolean ("reset", "Reset",
           "Reset all current ripples", FALSE,
-          G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
+          G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
 
   g_object_class_install_property (gobject_class, PROP_MODE,
       g_param_spec_enum ("mode", "Mode",
           "Mode", GST_TYPE_RIPPLETV_MODE, DEFAULT_MODE,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
 
   trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_rippletv_set_caps);
   trans_class->transform = GST_DEBUG_FUNCPTR (gst_rippletv_transform);
index 008da64..650a563 100644 (file)
@@ -86,6 +86,7 @@ gst_shagadelictv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
   structure = gst_caps_get_structure (incaps, 0);
 
+  GST_OBJECT_LOCK (filter);
   if (gst_structure_get_int (structure, "width", &filter->width) &&
       gst_structure_get_int (structure, "height", &filter->height)) {
     gint area = filter->width * filter->height;
@@ -99,6 +100,7 @@ gst_shagadelictv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
     gst_shagadelic_initialize (filter);
     ret = TRUE;
   }
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -176,6 +178,7 @@ gst_shagadelictv_transform (GstBaseTransform * trans, GstBuffer * in,
   src = (guint32 *) GST_BUFFER_DATA (in);
   dest = (guint32 *) GST_BUFFER_DATA (out);
 
+  GST_OBJECT_LOCK (filter);
   width = filter->width;
   height = filter->height;
 
@@ -210,6 +213,7 @@ gst_shagadelictv_transform (GstBaseTransform * trans, GstBuffer * in,
   filter->ry += filter->rvy;
   filter->bx += filter->bvx;
   filter->by += filter->bvy;
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
index ed129d9..bdda54d 100644 (file)
@@ -95,6 +95,7 @@ gst_streaktv_transform (GstBaseTransform * trans, GstBuffer * in,
   gint plane = filter->plane;
   guint stride_mask, stride_shift, stride;
 
+  GST_OBJECT_LOCK (filter);
   if (filter->feedback) {
     stride_mask = 0xfcfcfcfc;
     stride = 8;
@@ -136,6 +137,7 @@ gst_streaktv_transform (GstBaseTransform * trans, GstBuffer * in,
 
   plane++;
   filter->plane = plane & (PLANES - 1);
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -150,6 +152,7 @@ gst_streaktv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
   structure = gst_caps_get_structure (incaps, 0);
 
+  GST_OBJECT_LOCK (filter);
   if (gst_structure_get_int (structure, "width", &filter->width) &&
       gst_structure_get_int (structure, "height", &filter->height)) {
     gint i;
@@ -165,6 +168,7 @@ gst_streaktv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
     ret = TRUE;
   }
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
index 40620a5..2f7ac7c 100644 (file)
@@ -44,6 +44,7 @@
 #include "gstvertigo.h"
 
 #include <gst/video/video.h>
+#include <gst/controller/gstcontroller.h>
 
 GST_BOILERPLATE (GstVertigoTV, gst_vertigotv, GstVideoFilter,
     GST_TYPE_VIDEO_FILTER);
@@ -86,6 +87,7 @@ gst_vertigotv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
   structure = gst_caps_get_structure (incaps, 0);
 
+  GST_OBJECT_LOCK (filter);
   if (gst_structure_get_int (structure, "width", &filter->width) &&
       gst_structure_get_int (structure, "height", &filter->height)) {
     gint area = filter->width * filter->height;
@@ -99,6 +101,7 @@ gst_vertigotv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
     ret = TRUE;
   }
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -160,10 +163,23 @@ gst_vertigotv_transform (GstBaseTransform * trans, GstBuffer * in,
   guint32 v;
   gint x, y, ox, oy, i, width, height, area;
   GstFlowReturn ret = GST_FLOW_OK;
+  GstClockTime timestamp, stream_time;
+
+  timestamp = GST_BUFFER_TIMESTAMP (in);
+  stream_time =
+      gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME, timestamp);
+
+  GST_DEBUG_OBJECT (filter, "sync to %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (timestamp));
+
+  if (GST_CLOCK_TIME_IS_VALID (stream_time))
+    gst_object_sync_values (G_OBJECT (filter), stream_time);
 
   src = (guint32 *) GST_BUFFER_DATA (in);
   dest = (guint32 *) GST_BUFFER_DATA (out);
 
+  GST_OBJECT_LOCK (filter);
+
   width = filter->width;
   height = filter->height;
   area = width * height;
@@ -198,6 +214,7 @@ gst_vertigotv_transform (GstBaseTransform * trans, GstBuffer * in,
   p = filter->current_buffer;
   filter->current_buffer = filter->alt_buffer;
   filter->alt_buffer = p;
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -218,6 +235,7 @@ gst_vertigotv_set_property (GObject * object, guint prop_id,
 {
   GstVertigoTV *filter = GST_VERTIGOTV (object);
 
+  GST_OBJECT_LOCK (filter);
   switch (prop_id) {
     case PROP_SPEED:
       filter->phase_increment = g_value_get_float (value);
@@ -228,6 +246,7 @@ gst_vertigotv_set_property (GObject * object, guint prop_id,
     default:
       break;
   }
+  GST_OBJECT_UNLOCK (filter);
 }
 
 static void
index c51ed38..0b0c4ad 100644 (file)
@@ -93,6 +93,7 @@ gst_warptv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
   structure = gst_caps_get_structure (incaps, 0);
 
+  GST_OBJECT_LOCK (filter);
   if (gst_structure_get_int (structure, "width", &filter->width) &&
       gst_structure_get_int (structure, "height", &filter->height)) {
     g_free (filter->disttable);
@@ -106,6 +107,7 @@ gst_warptv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
     initDistTable (filter);
     ret = TRUE;
   }
+  GST_OBJECT_UNLOCK (filter);
 
   return ret;
 }
@@ -168,8 +170,7 @@ static GstFlowReturn
 gst_warptv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
 {
   GstWarpTV *warptv = GST_WARPTV (trans);
-  int width = warptv->width;
-  int height = warptv->height;
+  gint width, height;
   guint32 *src = (guint32 *) GST_BUFFER_DATA (in);
   guint32 *dest = (guint32 *) GST_BUFFER_DATA (out);
   gint xw, yw, cw;
@@ -178,6 +179,10 @@ gst_warptv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
   gint32 *ctable;
   GstFlowReturn ret = GST_FLOW_OK;
 
+  GST_OBJECT_LOCK (warptv);
+  width = warptv->width;
+  height = warptv->height;
+
   xw = (gint) (sin ((warptv->tval + 100) * M_PI / 128) * 30);
   yw = (gint) (sin ((warptv->tval) * M_PI / 256) * -35);
   cw = (gint) (sin ((warptv->tval - 70) * M_PI / 64) * 50);
@@ -221,6 +226,7 @@ gst_warptv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
   }
 
   warptv->tval = (warptv->tval + 1) & 511;
+  GST_OBJECT_UNLOCK (warptv);
 
   return ret;
 }