summaryrefslogtreecommitdiff
path: root/gst/gaudieffects
diff options
context:
space:
mode:
authorLuis de Bethencourt <luis@debethencourt.com>2010-10-27 14:57:36 +0200
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2010-10-28 18:52:07 +0200
commitcadfe13839574de5cadef578021319aa16f78b7c (patch)
tree74801ccc9765eb71772f5212d3494bc59d9e5e06 /gst/gaudieffects
parentcc1c6ee9e3bdc4c2eb5fc73f85e00c6b15afc1a5 (diff)
gaudieffects: made filter parameters dynamic and controllable
Diffstat (limited to 'gst/gaudieffects')
-rw-r--r--gst/gaudieffects/gstburn.c61
-rw-r--r--gst/gaudieffects/gstburn.h1
-rw-r--r--gst/gaudieffects/gstchromium.c87
-rw-r--r--gst/gaudieffects/gstchromium.h20
-rw-r--r--gst/gaudieffects/gstdilate.c227
-rw-r--r--gst/gaudieffects/gstdilate.h1
-rw-r--r--gst/gaudieffects/gstdodge.c13
-rw-r--r--gst/gaudieffects/gstexclusion.c61
-rw-r--r--gst/gaudieffects/gstexclusion.h1
-rw-r--r--gst/gaudieffects/gstplugin.c1
-rw-r--r--gst/gaudieffects/gstsolarize.c94
-rw-r--r--gst/gaudieffects/gstsolarize.h1
12 files changed, 434 insertions, 134 deletions
diff --git a/gst/gaudieffects/gstburn.c b/gst/gaudieffects/gstburn.c
index 08984b5b8..582d5e85b 100644
--- a/gst/gaudieffects/gstburn.c
+++ b/gst/gaudieffects/gstburn.c
@@ -87,16 +87,21 @@ enum
enum
{
- PROP_0,
+ PROP_0 = 0,
+ PROP_ADJUSTMENT,
PROP_SILENT
};
/* Initializations */
+#define DEFAULT_ADJUSTMENT 175
+
static gint gate_int (gint value, gint min, gint max);
-static void transform (guint32 * src, guint32 * dest, gint video_area);
+static void transform (guint32 * src, guint32 * dest, gint video_area,
+ gint adjustment);
/* The capabilities of the inputs and outputs. */
+
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
@@ -150,6 +155,11 @@ gst_burn_class_init (GstBurnClass * klass)
gobject_class->set_property = gst_burn_set_property;
gobject_class->get_property = gst_burn_get_property;
+ g_object_class_install_property (gobject_class, PROP_ADJUSTMENT,
+ g_param_spec_uint ("adjustment", "Adjustment",
+ "Adjustment parameter", 0, 256, DEFAULT_ADJUSTMENT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
+
g_object_class_install_property (gobject_class, PROP_SILENT,
g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
@@ -158,7 +168,7 @@ gst_burn_class_init (GstBurnClass * klass)
trans_class->transform = GST_DEBUG_FUNCPTR (gst_burn_transform);
}
-/* Initialize the new element,
+/* Initialize the element,
* instantiate pads and add them to element,
* set pad calback functions, and
* initialize instance structure.
@@ -166,6 +176,7 @@ gst_burn_class_init (GstBurnClass * klass)
static void
gst_burn_init (GstBurn * filter, GstBurnClass * gclass)
{
+ filter->adjustment = DEFAULT_ADJUSTMENT;
filter->silent = FALSE;
}
@@ -179,6 +190,9 @@ gst_burn_set_property (GObject * object, guint prop_id,
case PROP_SILENT:
filter->silent = g_value_get_boolean (value);
break;
+ case PROP_ADJUSTMENT:
+ filter->adjustment = g_value_get_uint (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -191,14 +205,19 @@ gst_burn_get_property (GObject * object, guint prop_id,
{
GstBurn *filter = GST_BURN (object);
+ GST_OBJECT_LOCK (filter);
switch (prop_id) {
case PROP_SILENT:
g_value_set_boolean (value, filter->silent);
break;
+ case PROP_ADJUSTMENT:
+ g_value_set_uint (value, filter->adjustment);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
+ GST_OBJECT_UNLOCK (filter);
}
/* GstElement vmethod implementations */
@@ -210,12 +229,16 @@ gst_burn_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
{
GstBurn *filter = GST_BURN (btrans);
GstStructure *structure;
- gboolean ret = TRUE;
+ gboolean ret = FALSE;
structure = gst_caps_get_structure (incaps, 0);
- ret &= gst_structure_get_int (structure, "width", &filter->width);
- ret &= gst_structure_get_int (structure, "height", &filter->height);
+ 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;
}
@@ -226,12 +249,30 @@ gst_burn_transform (GstBaseTransform * btrans,
GstBuffer * in_buf, GstBuffer * out_buf)
{
GstBurn *filter = GST_BURN (btrans);
- gint video_size;
+ gint video_size, adjustment;
guint32 *src = (guint32 *) GST_BUFFER_DATA (in_buf);
guint32 *dest = (guint32 *) GST_BUFFER_DATA (out_buf);
+ GstClockTime timestamp;
+ gint64 stream_time;
video_size = filter->width * filter->height;
- transform (src, dest, video_size);
+
+ /* GstController: update the properties */
+ timestamp = GST_BUFFER_TIMESTAMP (in_buf);
+ stream_time =
+ gst_segment_to_stream_time (&btrans->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);
+
+ GST_OBJECT_LOCK (filter);
+ adjustment = filter->adjustment;
+ GST_OBJECT_UNLOCK (filter);
+
+ transform (src, dest, video_size, adjustment);
return GST_FLOW_OK;
}
@@ -248,7 +289,6 @@ gst_burn_plugin_init (GstPlugin * burn)
}
/*** Now the image processing work.... ***/
-
/* Keep the values inbounds. */
static gint
gate_int (gint value, gint min, gint max)
@@ -264,11 +304,10 @@ gate_int (gint value, gint min, gint max)
/* Transform processes each frame. */
static void
-transform (guint32 * src, guint32 * dest, gint video_area)
+transform (guint32 * src, guint32 * dest, gint video_area, gint adjustment)
{
guint32 in, red, green, blue;
gint x;
- gint adjustment = 175;
for (x = 0; x < video_area; x++) {
in = *src++;
diff --git a/gst/gaudieffects/gstburn.h b/gst/gaudieffects/gstburn.h
index d6b9d4c4f..1a3ed58e1 100644
--- a/gst/gaudieffects/gstburn.h
+++ b/gst/gaudieffects/gstburn.h
@@ -75,6 +75,7 @@ struct _GstBurn
gint width, height;
+ gint adjustment;
gboolean silent;
};
diff --git a/gst/gaudieffects/gstchromium.c b/gst/gaudieffects/gstchromium.c
index 4f748ff6c..94d3b1505 100644
--- a/gst/gaudieffects/gstchromium.c
+++ b/gst/gaudieffects/gstchromium.c
@@ -61,14 +61,14 @@
# include <config.h>
#endif
-#include <gst/gst.h>
#include <math.h>
+#include <gst/gst.h>
+#include <gst/controller/gstcontroller.h>
#include "gstplugin.h"
#include "gstchromium.h"
#include <gst/video/video.h>
-#include <gst/controller/gstcontroller.h>
GST_DEBUG_CATEGORY_STATIC (gst_chromium_debug);
#define GST_CAT_DEFAULT gst_chromium_debug
@@ -87,12 +87,17 @@ enum
enum
{
- PROP_0,
+ PROP_0 = 0,
+ PROP_EDGE_A,
+ PROP_EDGE_B,
PROP_SILENT
};
/* Initializations */
+#define DEFAULT_EDGE_A 200
+#define DEFAULT_EDGE_B 1
+
const float pi = 3.141582f;
gint cosTablePi = 512;
@@ -106,7 +111,8 @@ static gint gate_int (gint value, gint min, gint max);
void setup_cos_table (void);
static gint cos_from_table (int angle);
static inline int abs_int (int val);
-static void transform (guint32 * src, guint32 * dest, gint video_area);
+static void transform (guint32 * src, guint32 * dest, gint video_area,
+ gint edge_a, gint edge_b);
/* The capabilities of the inputs and outputs. */
@@ -164,6 +170,16 @@ gst_chromium_class_init (GstChromiumClass * klass)
gobject_class->set_property = gst_chromium_set_property;
gobject_class->get_property = gst_chromium_get_property;
+ g_object_class_install_property (gobject_class, PROP_EDGE_A,
+ g_param_spec_uint ("edge-a", "Edge A",
+ "First edge parameter", 0, 256, DEFAULT_EDGE_A,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
+
+ g_object_class_install_property (gobject_class, PROP_EDGE_B,
+ g_param_spec_uint ("edge-b", "Edge B",
+ "Second edge parameter", 0, 256, DEFAULT_EDGE_B,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
+
g_object_class_install_property (gobject_class, PROP_SILENT,
g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
@@ -172,7 +188,7 @@ gst_chromium_class_init (GstChromiumClass * klass)
trans_class->transform = GST_DEBUG_FUNCPTR (gst_chromium_transform);
}
-/* Initialize the new element,
+/* Initialize the element,
* instantiate pads and add them to element,
* set pad calback functions, and
* initialize instance structure.
@@ -180,6 +196,8 @@ gst_chromium_class_init (GstChromiumClass * klass)
static void
gst_chromium_init (GstChromium * filter, GstChromiumClass * gclass)
{
+ filter->edge_a = DEFAULT_EDGE_A;
+ filter->edge_b = DEFAULT_EDGE_B;
filter->silent = FALSE;
setup_cos_table ();
@@ -195,26 +213,41 @@ gst_chromium_set_property (GObject * object, guint prop_id,
case PROP_SILENT:
filter->silent = g_value_get_boolean (value);
break;
+ case PROP_EDGE_A:
+ filter->edge_a = g_value_get_uint (value);
+ break;
+ case PROP_EDGE_B:
+ filter->edge_b = g_value_get_uint (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
+
static void
gst_chromium_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstChromium *filter = GST_CHROMIUM (object);
+ GST_OBJECT_LOCK (filter);
switch (prop_id) {
case PROP_SILENT:
g_value_set_boolean (value, filter->silent);
break;
+ case PROP_EDGE_A:
+ g_value_set_uint (value, filter->edge_a);
+ break;
+ case PROP_EDGE_B:
+ g_value_set_uint (value, filter->edge_b);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
+ GST_OBJECT_UNLOCK (filter);
}
/* GstElement vmethod implementations */
@@ -226,12 +259,16 @@ gst_chromium_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
{
GstChromium *filter = GST_CHROMIUM (btrans);
GstStructure *structure;
- gboolean ret = TRUE;
+ gboolean ret = FALSE;
structure = gst_caps_get_structure (incaps, 0);
- ret &= gst_structure_get_int (structure, "width", &filter->width);
- ret &= gst_structure_get_int (structure, "height", &filter->height);
+ 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;
}
@@ -242,12 +279,30 @@ gst_chromium_transform (GstBaseTransform * btrans,
GstBuffer * in_buf, GstBuffer * out_buf)
{
GstChromium *filter = GST_CHROMIUM (btrans);
- gint video_size;
+ gint video_size, edge_a, edge_b;
guint32 *src = (guint32 *) GST_BUFFER_DATA (in_buf);
guint32 *dest = (guint32 *) GST_BUFFER_DATA (out_buf);
+ GstClockTime timestamp;
+ gint64 stream_time;
+
+ /* GstController: update the properties */
+ timestamp = GST_BUFFER_TIMESTAMP (in_buf);
+ stream_time =
+ gst_segment_to_stream_time (&btrans->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);
+
+ GST_OBJECT_LOCK (filter);
+ edge_a = filter->edge_a;
+ edge_b = filter->edge_b;
+ GST_OBJECT_UNLOCK (filter);
video_size = filter->width * filter->height;
- transform (src, dest, video_size);
+ transform (src, dest, video_size, edge_a, edge_b);
return GST_FLOW_OK;
}
@@ -258,15 +313,14 @@ gboolean
gst_chromium_plugin_init (GstPlugin * chromium)
{
/* debug category for fltering log messages */
- GST_DEBUG_CATEGORY_INIT (gst_chromium_debug, "chromium",
- 0, "Template chromium");
+ GST_DEBUG_CATEGORY_INIT (gst_chromium_debug, "chromium", 0,
+ "Template chromium");
return gst_element_register (chromium, "chromium", GST_RANK_NONE,
GST_TYPE_CHROMIUM);
}
/*** Now the image processing work.... ***/
-
/* Set up the cosine table. */
void
setup_cos_table (void)
@@ -313,14 +367,11 @@ cos_from_table (int angle)
/* Transform processes each frame. */
static void
-transform (guint32 * src, guint32 * dest, gint video_area)
+transform (guint32 * src, guint32 * dest, gint video_area,
+ gint edge_a, gint edge_b)
{
guint32 in, red, green, blue;
gint x;
- guint32 edge_a, edge_b;
-
- edge_a = 200;
- edge_b = 1;
for (x = 0; x < video_area; x++) {
in = *src++;
diff --git a/gst/gaudieffects/gstchromium.h b/gst/gaudieffects/gstchromium.h
index 2cd63cd6c..4f41f1d7a 100644
--- a/gst/gaudieffects/gstchromium.h
+++ b/gst/gaudieffects/gstchromium.h
@@ -47,14 +47,12 @@
#define __GST_CHROMIUM_H__
#include <gst/gst.h>
-
+#include <gst/video/video.h>
#include <gst/video/gstvideofilter.h>
G_BEGIN_DECLS
-/* #defines don't like whitespacey bits */
-#define GST_TYPE_CHROMIUM \
- (gst_chromium_get_type())
+#define GST_TYPE_CHROMIUM (gst_chromium_get_type())
#define GST_CHROMIUM(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CHROMIUM,GstChromium))
#define GST_CHROMIUM_CLASS(klass) \
@@ -64,20 +62,20 @@ G_BEGIN_DECLS
#define GST_IS_CHROMIUM_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CHROMIUM))
-typedef struct _GstChromium GstChromium;
-typedef struct _GstChromiumClass GstChromiumClass;
+typedef struct GstChromium GstChromium;
+typedef struct GstChromiumClass GstChromiumClass;
-struct _GstChromium
+struct GstChromium
{
GstVideoFilter videofilter;
-
- /* < private > */
gint width, height;
+ /* < private > */
+ gint edge_a, edge_b;
gboolean silent;
};
-struct _GstChromiumClass
+struct GstChromiumClass
{
GstVideoFilterClass parent_class;
};
@@ -86,4 +84,4 @@ GType gst_chromium_get_type (void);
G_END_DECLS
-#endif /* __GST_CHROMIUM_H__ */
+#endif
diff --git a/gst/gaudieffects/gstdilate.c b/gst/gaudieffects/gstdilate.c
index 5eb3c62dd..c89123c16 100644
--- a/gst/gaudieffects/gstdilate.c
+++ b/gst/gaudieffects/gstdilate.c
@@ -88,13 +88,16 @@ enum
enum
{
PROP_0,
+ PROP_ERODE,
PROP_SILENT
};
/* Initializations */
+#define DEFAULT_ERODE FALSE
+
static void transform (guint32 * src, guint32 * dest, gint video_area,
- gint width, gint height);
+ gint width, gint height, gboolean erode);
static inline guint32 get_luminance (guint32 in);
/* The capabilities of the inputs and outputs. */
@@ -152,6 +155,10 @@ gst_dilate_class_init (GstDilateClass * klass)
gobject_class->set_property = gst_dilate_set_property;
gobject_class->get_property = gst_dilate_get_property;
+ g_object_class_install_property (gobject_class, PROP_ERODE,
+ g_param_spec_boolean ("erode", "Erode", "Erode parameter", FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
+
g_object_class_install_property (gobject_class, PROP_SILENT,
g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
@@ -160,7 +167,7 @@ gst_dilate_class_init (GstDilateClass * klass)
trans_class->transform = GST_DEBUG_FUNCPTR (gst_dilate_transform);
}
-/* Initialize the new element,
+/* Initialize the element,
* instantiate pads and add them to element,
* set pad calback functions, and
* initialize instance structure.
@@ -168,6 +175,7 @@ gst_dilate_class_init (GstDilateClass * klass)
static void
gst_dilate_init (GstDilate * filter, GstDilateClass * gclass)
{
+ filter->erode = DEFAULT_ERODE;
filter->silent = FALSE;
}
@@ -181,6 +189,9 @@ gst_dilate_set_property (GObject * object, guint prop_id,
case PROP_SILENT:
filter->silent = g_value_get_boolean (value);
break;
+ case PROP_ERODE:
+ filter->erode = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -193,14 +204,19 @@ gst_dilate_get_property (GObject * object, guint prop_id,
{
GstDilate *filter = GST_DILATE (object);
+ GST_OBJECT_LOCK (filter);
switch (prop_id) {
case PROP_SILENT:
g_value_set_boolean (value, filter->silent);
break;
+ case PROP_ERODE:
+ g_value_set_boolean (value, filter->erode);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
+ GST_OBJECT_UNLOCK (filter);
}
/* GstElement vmethod implementations */
@@ -215,8 +231,13 @@ gst_dilate_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
gboolean ret = TRUE;
structure = gst_caps_get_structure (incaps, 0);
- ret &= gst_structure_get_int (structure, "width", &filter->width);
- ret &= gst_structure_get_int (structure, "height", &filter->height);
+
+ 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;
}
@@ -228,13 +249,30 @@ gst_dilate_transform (GstBaseTransform * btrans,
{
GstDilate *filter = GST_DILATE (btrans);
gint video_size;
-
+ gboolean erode;
guint32 *src = (guint32 *) GST_BUFFER_DATA (in_buf);
guint32 *dest = (guint32 *) GST_BUFFER_DATA (out_buf);
+ GstClockTime timestamp;
+ gint64 stream_time;
video_size = filter->width * filter->height;
- transform (src, dest, video_size, filter->width, filter->height);
+ /* GstController: update the properties */
+ timestamp = GST_BUFFER_TIMESTAMP (in_buf);
+ stream_time =
+ gst_segment_to_stream_time (&btrans->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);
+
+ GST_OBJECT_LOCK (filter);
+ erode = filter->erode;
+ GST_OBJECT_UNLOCK (filter);
+
+ transform (src, dest, video_size, filter->width, filter->height, erode);
return GST_FLOW_OK;
}
@@ -271,72 +309,133 @@ get_luminance (guint32 in)
/* Transform processes each frame. */
static void
transform (guint32 * src, guint32 * dest, gint video_area, gint width,
- gint height)
+ gint height, gboolean erode)
{
guint32 out_luminance, down_luminance, right_luminance;
guint32 up_luminance, left_luminance;
guint32 *src_end = src + video_area;
-
- while (src != src_end) {
- guint32 *src_line_start = src;
- guint32 *src_line_end = src + width;
- guint32 *up;
- guint32 *left;
- guint32 *down;
- guint32 *right;
-
- while (src != src_line_end) {
-
- up = src - width;
- if (up < src) {
- up = src;
- }
-
- left = src - 1;
- if (left < src_line_start) {
- left = src;
- }
-
- down = src + width;
- if (down >= src_end) {
- down = src;
- }
-
- right = src + 1;
- if (right >= src_line_end) {
- right = src;
- }
-
- *dest = *src;
- out_luminance = get_luminance (*src);
-
- down_luminance = get_luminance (*down);
- if (down_luminance > out_luminance) {
- *dest = *down;
- out_luminance = down_luminance;
- }
-
- right_luminance = get_luminance (*right);
- if (right_luminance > out_luminance) {
- *dest = *right;
- out_luminance = right_luminance;
- }
-
- up_luminance = get_luminance (*up);
- if (up_luminance > out_luminance) {
- *dest = *up;
- out_luminance = up_luminance;
+ guint32 *up;
+ guint32 *left;
+ guint32 *down;
+ guint32 *right;
+
+ if (erode) {
+
+ while (src != src_end) {
+ guint32 *src_line_start = src;
+ guint32 *src_line_end = src + width;
+ while (src != src_line_end) {
+
+ up = src - width;
+ if (up < src) {
+ up = src;
+ }
+
+ left = src - 1;
+ if (left < src_line_start) {
+ left = src;
+ }
+
+ down = src + width;
+ if (down >= src_end) {
+ down = src;
+ }
+
+ right = src + 1;
+ if (right >= src_line_end) {
+ right = src;
+ }
+
+ *dest = *src;
+ out_luminance = get_luminance (*src);
+
+ down_luminance = get_luminance (*down);
+ if (down_luminance < out_luminance) {
+ *dest = *down;
+ out_luminance = down_luminance;
+ }
+
+ right_luminance = get_luminance (*right);
+ if (right_luminance < out_luminance) {
+ *dest = *right;
+ out_luminance = right_luminance;
+ }
+
+ up_luminance = get_luminance (*up);
+ if (up_luminance < out_luminance) {
+ *dest = *up;
+ out_luminance = up_luminance;
+ }
+
+ left_luminance = get_luminance (*left);
+ if (left_luminance < out_luminance) {
+ *dest = *left;
+ out_luminance = left_luminance;
+ }
+
+ src += 1;
+ dest += 1;
}
+ }
- left_luminance = get_luminance (*left);
- if (left_luminance > out_luminance) {
- *dest = *left;
- out_luminance = left_luminance;
+ } else {
+
+ while (src != src_end) {
+ guint32 *src_line_start = src;
+ guint32 *src_line_end = src + width;
+ while (src != src_line_end) {
+
+ up = src - width;
+ if (up < src) {
+ up = src;
+ }
+
+ left = src - 1;
+ if (left < src_line_start) {
+ left = src;
+ }
+
+ down = src + width;
+ if (down >= src_end) {
+ down = src;
+ }
+
+ right = src + 1;
+ if (right >= src_line_end) {
+ right = src;
+ }
+
+ *dest = *src;
+ out_luminance = get_luminance (*src);
+
+ down_luminance = get_luminance (*down);
+ if (down_luminance > out_luminance) {
+ *dest = *down;
+ out_luminance = down_luminance;
+ }
+
+ right_luminance = get_luminance (*right);
+ if (right_luminance > out_luminance) {
+ *dest = *right;
+ out_luminance = right_luminance;
+ }
+
+ up_luminance = get_luminance (*up);
+ if (up_luminance > out_luminance) {
+ *dest = *up;
+ out_luminance = up_luminance;
+ }
+
+ left_luminance = get_luminance (*left);
+ if (left_luminance > out_luminance) {
+ *dest = *left;
+ out_luminance = left_luminance;
+ }
+
+ src += 1;
+ dest += 1;
}
-
- src += 1;
- dest += 1;
}
}
}
diff --git a/gst/gaudieffects/gstdilate.h b/gst/gaudieffects/gstdilate.h
index 8a3b50290..29e32f127 100644
--- a/gst/gaudieffects/gstdilate.h
+++ b/gst/gaudieffects/gstdilate.h
@@ -76,6 +76,7 @@ struct _GstDilate
gint width, height;
gboolean silent;
+ gboolean erode;
};
struct _GstDilateClass
diff --git a/gst/gaudieffects/gstdodge.c b/gst/gaudieffects/gstdodge.c
index cf42b5331..ff61aa7e5 100644
--- a/gst/gaudieffects/gstdodge.c
+++ b/gst/gaudieffects/gstdodge.c
@@ -159,7 +159,7 @@ gst_dodge_class_init (GstDodgeClass * klass)
trans_class->transform = GST_DEBUG_FUNCPTR (gst_dodge_transform);
}
-/* Initialize the new element,
+/* Initialize the element,
* instantiate pads and add them to element,
* set pad calback functions, and
* initialize instance structure.
@@ -192,6 +192,7 @@ gst_dodge_get_property (GObject * object, guint prop_id,
{
GstDodge *filter = GST_DODGE (object);
+ GST_OBJECT_LOCK (filter);
switch (prop_id) {
case PROP_SILENT:
g_value_set_boolean (value, filter->silent);
@@ -200,6 +201,7 @@ gst_dodge_get_property (GObject * object, guint prop_id,
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
+ GST_OBJECT_UNLOCK (filter);
}
/* GstElement vmethod implementations */
@@ -214,8 +216,13 @@ gst_dodge_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
gboolean ret = TRUE;
structure = gst_caps_get_structure (incaps, 0);
- ret &= gst_structure_get_int (structure, "width", &filter->width);
- ret &= gst_structure_get_int (structure, "height", &filter->height);
+
+ 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;
}
diff --git a/gst/gaudieffects/gstexclusion.c b/gst/gaudieffects/gstexclusion.c
index 59325d7ef..0b8f5d592 100644
--- a/gst/gaudieffects/gstexclusion.c
+++ b/gst/gaudieffects/gstexclusion.c
@@ -87,14 +87,18 @@ enum
enum
{
- PROP_0,
+ PROP_0 = 0,
+ PROP_FACTOR,
PROP_SILENT
};
/* Initializations */
+#define DEFAULT_FACTOR 175
+
static gint gate_int (gint value, gint min, gint max);
-static void transform (guint32 * src, guint32 * dest, gint video_area);
+static void transform (guint32 * src, guint32 * dest, gint video_area,
+ gint factor);
/* The capabilities of the inputs and outputs. */
@@ -152,6 +156,11 @@ gst_exclusion_class_init (GstExclusionClass * klass)
gobject_class->set_property = gst_exclusion_set_property;
gobject_class->get_property = gst_exclusion_get_property;
+ g_object_class_install_property (gobject_class, PROP_FACTOR,
+ g_param_spec_uint ("factor", "Factor",
+ "Exclusion factor parameter", 0, 175, DEFAULT_FACTOR,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
+
g_object_class_install_property (gobject_class, PROP_SILENT,
g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
@@ -160,7 +169,7 @@ gst_exclusion_class_init (GstExclusionClass * klass)
trans_class->transform = GST_DEBUG_FUNCPTR (gst_exclusion_transform);
}
-/* Initialize the new element,
+/* Initialize the element,
* instantiate pads and add them to element,
* set pad calback functions, and
* initialize instance structure.
@@ -168,6 +177,7 @@ gst_exclusion_class_init (GstExclusionClass * klass)
static void
gst_exclusion_init (GstExclusion * filter, GstExclusionClass * gclass)
{
+ filter->factor = DEFAULT_FACTOR;
filter->silent = FALSE;
}
@@ -181,6 +191,9 @@ gst_exclusion_set_property (GObject * object, guint prop_id,
case PROP_SILENT:
filter->silent = g_value_get_boolean (value);
break;
+ case PROP_FACTOR:
+ filter->factor = g_value_get_uint (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -193,18 +206,22 @@ gst_exclusion_get_property (GObject * object, guint prop_id,
{
GstExclusion *filter = GST_EXCLUSION (object);
+ GST_OBJECT_LOCK (filter);
switch (prop_id) {
case PROP_SILENT:
g_value_set_boolean (value, filter->silent);
break;
+ case PROP_FACTOR:
+ g_value_set_uint (value, filter->factor);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
+ GST_OBJECT_UNLOCK (filter);
}
/* GstElement vmethod implementations */
-
/* Handle the link with other elements. */
static gboolean
gst_exclusion_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
@@ -212,11 +229,15 @@ gst_exclusion_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
{
GstExclusion *filter = GST_EXCLUSION (btrans);
GstStructure *structure;
- gboolean ret = TRUE;
+ gboolean ret = FALSE;
+ GST_OBJECT_LOCK (filter);
structure = gst_caps_get_structure (incaps, 0);
- ret &= gst_structure_get_int (structure, "width", &filter->width);
- ret &= gst_structure_get_int (structure, "height", &filter->height);
+ 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;
}
@@ -227,13 +248,29 @@ gst_exclusion_transform (GstBaseTransform * btrans,
GstBuffer * in_buf, GstBuffer * out_buf)
{
GstExclusion *filter = GST_EXCLUSION (btrans);
- gint video_size;
+ gint video_size, factor;
guint32 *src = (guint32 *) GST_BUFFER_DATA (in_buf);
guint32 *dest = (guint32 *) GST_BUFFER_DATA (out_buf);
+ GstClockTime timestamp;
+ gint64 stream_time;
- video_size = filter->width * filter->height;
+ /* GstController: update the properties */
+ timestamp = GST_BUFFER_TIMESTAMP (in_buf);
+ stream_time =
+ gst_segment_to_stream_time (&btrans->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);
- transform (src, dest, video_size);
+ GST_OBJECT_LOCK (filter);
+ factor = filter->factor;
+ GST_OBJECT_UNLOCK (filter);
+
+ video_size = filter->width * filter->height;
+ transform (src, dest, video_size, factor);
return GST_FLOW_OK;
}
@@ -252,7 +289,6 @@ gst_exclusion_plugin_init (GstPlugin * exclusion)
}
/*** Now the image processing work.... ***/
-
/* Keep the values inbounds. */
static gint
gate_int (gint value, gint min, gint max)
@@ -268,11 +304,10 @@ gate_int (gint value, gint min, gint max)
/* Transform processes each frame. */
static void
-transform (guint32 * src, guint32 * dest, gint video_area)
+transform (guint32 * src, guint32 * dest, gint video_area, gint factor)
{
guint32 in, red, green, blue;
gint x;
- gint factor = 175;
for (x = 0; x < video_area; x++) {
in = *src++;
diff --git a/gst/gaudieffects/gstexclusion.h b/gst/gaudieffects/gstexclusion.h
index 0ff7f9629..b47eef1b9 100644
--- a/gst/gaudieffects/gstexclusion.h
+++ b/gst/gaudieffects/gstexclusion.h
@@ -75,6 +75,7 @@ struct _GstExclusion
gint width, height;
+ gint factor;
gboolean silent;
};
diff --git a/gst/gaudieffects/gstplugin.c b/gst/gaudieffects/gstplugin.c
index 536bcb7e0..ea2c77b6b 100644
--- a/gst/gaudieffects/gstplugin.c
+++ b/gst/gaudieffects/gstplugin.c
@@ -63,6 +63,7 @@
static gboolean
plugin_init (GstPlugin * plugin)
{
+ gst_controller_init (NULL, NULL);
gboolean ret = TRUE;
ret &= gst_burn_plugin_init (plugin);
diff --git a/gst/gaudieffects/gstsolarize.c b/gst/gaudieffects/gstsolarize.c
index 46b7df6a5..8cce8dbcf 100644
--- a/gst/gaudieffects/gstsolarize.c
+++ b/gst/gaudieffects/gstsolarize.c
@@ -87,14 +87,22 @@ enum
enum
{
- PROP_0,
+ PROP_0 = 0,
+ PROP_THRESHOLD,
+ PROP_START,
+ PROP_END,
PROP_SILENT
};
/* Initializations */
+#define DEFAULT_THRESHOLD 127
+#define DEFAULT_START 50
+#define DEFAULT_END 185
+
static gint gate_int (gint value, gint min, gint max);
-static void transform (guint32 * src, guint32 * dest, gint video_area);
+static void transform (guint32 * src, guint32 * dest, gint video_area,
+ gint threshold, gint start, gint end);
/* The capabilities of the inputs and outputs. */
@@ -152,6 +160,21 @@ gst_solarize_class_init (GstSolarizeClass * klass)
gobject_class->set_property = gst_solarize_set_property;
gobject_class->get_property = gst_solarize_get_property;
+ g_object_class_install_property (gobject_class, PROP_THRESHOLD,
+ g_param_spec_uint ("threshold", "Threshold",
+ "Threshold parameter", 0, 256, DEFAULT_THRESHOLD,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
+
+ g_object_class_install_property (gobject_class, PROP_START,
+ g_param_spec_uint ("start", "Start",
+ "Start parameter", 0, 256, DEFAULT_START,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
+
+ g_object_class_install_property (gobject_class, PROP_END,
+ g_param_spec_uint ("end", "End",
+ "End parameter", 0, 256, DEFAULT_END,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
+
g_object_class_install_property (gobject_class, PROP_SILENT,
g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
@@ -160,7 +183,7 @@ gst_solarize_class_init (GstSolarizeClass * klass)
trans_class->transform = GST_DEBUG_FUNCPTR (gst_solarize_transform);
}
-/* Initialize the new element,
+/* Initialize the element,
* instantiate pads and add them to element,
* set pad calback functions, and
* initialize instance structure.
@@ -168,6 +191,9 @@ gst_solarize_class_init (GstSolarizeClass * klass)
static void
gst_solarize_init (GstSolarize * filter, GstSolarizeClass * gclass)
{
+ filter->threshold = DEFAULT_THRESHOLD;
+ filter->start = DEFAULT_START;
+ filter->end = DEFAULT_END;
filter->silent = FALSE;
}
@@ -181,6 +207,15 @@ gst_solarize_set_property (GObject * object, guint prop_id,
case PROP_SILENT:
filter->silent = g_value_get_boolean (value);
break;
+ case PROP_THRESHOLD:
+ filter->threshold = g_value_get_uint (value);
+ break;
+ case PROP_START:
+ filter->start = g_value_get_uint (value);
+ break;
+ case PROP_END:
+ filter->end = g_value_get_uint (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -193,14 +228,25 @@ gst_solarize_get_property (GObject * object, guint prop_id,
{
GstSolarize *filter = GST_SOLARIZE (object);
+ GST_OBJECT_LOCK (filter);
switch (prop_id) {
case PROP_SILENT:
g_value_set_boolean (value, filter->silent);
break;
+ case PROP_THRESHOLD:
+ g_value_set_uint (value, filter->threshold);
+ break;
+ case PROP_START:
+ g_value_set_uint (value, filter->start);
+ break;
+ case PROP_END:
+ g_value_set_uint (value, filter->end);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
+ GST_OBJECT_UNLOCK (filter);
}
/* GstElement vmethod implementations */
@@ -212,11 +258,15 @@ gst_solarize_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
{
GstSolarize *filter = GST_SOLARIZE (btrans);
GstStructure *structure;
- gboolean ret = TRUE;
+ gboolean ret = FALSE;
+ GST_OBJECT_LOCK (filter);
structure = gst_caps_get_structure (incaps, 0);
- ret &= gst_structure_get_int (structure, "width", &filter->width);
- ret &= gst_structure_get_int (structure, "height", &filter->height);
+ 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;
}
@@ -227,13 +277,31 @@ gst_solarize_transform (GstBaseTransform * btrans,
GstBuffer * in_buf, GstBuffer * out_buf)
{
GstSolarize *filter = GST_SOLARIZE (btrans);
- gint video_size;
+ gint video_size, threshold, start, end;
guint32 *src = (guint32 *) GST_BUFFER_DATA (in_buf);
guint32 *dest = (guint32 *) GST_BUFFER_DATA (out_buf);
+ GstClockTime timestamp;
+ gint64 stream_time;
- video_size = filter->width * filter->height;
+ /* GstController: update the properties */
+ timestamp = GST_BUFFER_TIMESTAMP (in_buf);
+ stream_time =
+ gst_segment_to_stream_time (&btrans->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);
- transform (src, dest, video_size);
+ GST_OBJECT_LOCK (filter);
+ threshold = filter->threshold;
+ start = filter->start;
+ end = filter->end;
+ GST_OBJECT_UNLOCK (filter);
+
+ video_size = filter->width * filter->height;
+ transform (src, dest, video_size, threshold, start, end);
return GST_FLOW_OK;
}
@@ -252,7 +320,6 @@ gst_solarize_plugin_init (GstPlugin * solarize)
}
/*** Now the image processing work.... ***/
-
/* Keep the values inbounds. */
static gint
gate_int (gint value, gint min, gint max)
@@ -268,14 +335,12 @@ gate_int (gint value, gint min, gint max)
/* Transform processes each frame. */
static void
-transform (guint32 * src, guint32 * dest, gint video_area)
+transform (guint32 * src, guint32 * dest, gint video_area,
+ gint threshold, gint start, gint end)
{
guint32 in;
guint32 color[3];
gint x, c;
- gint threshold = 127;
- gint start = 50;
- gint end = 185;
gint floor = 0;
gint ceiling = 255;
@@ -306,6 +371,7 @@ transform (guint32 * src, guint32 * dest, gint video_area)
color[1] = (in >> 8) & 0xff;
color[2] = (in) & 0xff;
+
/* Loop through colors. */
for (c = 0; c < 3; c++) {
param = color[c];
diff --git a/gst/gaudieffects/gstsolarize.h b/gst/gaudieffects/gstsolarize.h
index 885687d03..0d26a85e6 100644
--- a/gst/gaudieffects/gstsolarize.h
+++ b/gst/gaudieffects/gstsolarize.h
@@ -75,6 +75,7 @@ struct _GstSolarize
gint width, height;
+ gint threshold, start, end;
gboolean silent;
};