dicetv: Clean up dicetv element and fix some smaller issues

This fixes a memory leak (the dice map) and a crash when
setting the square-bits property before caps are set.
This commit is contained in:
Sebastian Dröge 2009-06-15 17:21:58 +02:00
parent d1ad31b9b3
commit 0cbdfcbc22

View file

@ -1,5 +1,6 @@
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) <2009> Sebastian Dröge <sebastian.droege@collabora.co.uk>
*
* dice.c: a 'dicing' effect
* copyright (c) 2001 Sam Mertens. This code is subject to the provisions of
@ -14,12 +15,13 @@
#include "config.h"
#endif
#include <gst/video/gstvideofilter.h>
#include <string.h>
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/video/gstvideofilter.h>
#include <gst/controller/gstcontroller.h>
#define GST_TYPE_DICETV \
(gst_dicetv_get_type())
@ -66,16 +68,10 @@ struct _GstDiceTVClass
GstVideoFilterClass parent_class;
};
GType gst_dicetv_get_type (void);
GST_BOILERPLATE (GstDiceTV, gst_dicetv, GstVideoFilter, GST_TYPE_VIDEO_FILTER);
static void gst_dicetv_create_map (GstDiceTV * filter);
static const GstElementDetails gst_dicetv_details =
GST_ELEMENT_DETAILS ("DiceTV effect",
"Filter/Effect/Video",
"'Dices' the screen up into many small squares",
"Wim Taymans <wim.taymans@chello.be>");
static GstStaticPadTemplate gst_dicetv_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
@ -92,8 +88,6 @@ static GstStaticPadTemplate gst_dicetv_sink_template =
GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_xBGR)
);
static GstVideoFilterClass *parent_class = NULL;
enum
{
ARG_0,
@ -114,7 +108,7 @@ gst_dicetv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
gst_structure_get_int (structure, "height", &filter->height)) {
g_free (filter->dicemap);
filter->dicemap =
(gchar *) g_malloc (filter->height * filter->width * sizeof (char));
(gchar *) g_malloc (filter->height * filter->width * sizeof (gchar));
gst_dicetv_create_map (filter);
ret = TRUE;
}
@ -126,13 +120,11 @@ static gboolean
gst_dicetv_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
guint * size)
{
GstDiceTV *filter;
GstDiceTV *filter = GST_DICETV (btrans);
GstStructure *structure;
gboolean ret = FALSE;
gint width, height;
filter = GST_DICETV (btrans);
structure = gst_caps_get_structure (caps, 0);
if (gst_structure_get_int (structure, "width", &width) &&
@ -146,10 +138,10 @@ gst_dicetv_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
return ret;
}
static unsigned int
static inline guint
fastrand (void)
{
static unsigned int fastrand_val;
static guint fastrand_val;
return (fastrand_val = fastrand_val * 1103515245 + 12345);
}
@ -157,17 +149,25 @@ fastrand (void)
static GstFlowReturn
gst_dicetv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
{
GstDiceTV *filter;
GstDiceTV *filter = GST_DICETV (trans);
guint32 *src, *dest;
gint i, map_x, map_y, map_i, base, dx, dy, di;
gint video_width, g_cube_bits, g_cube_size;
GstFlowReturn ret = GST_FLOW_OK;
GstClockTime timestamp, stream_time;
filter = GST_DICETV (trans);
src = (guint32 *) GST_BUFFER_DATA (in);
dest = (guint32 *) GST_BUFFER_DATA (out);
gst_buffer_copy_metadata (out, in, GST_BUFFER_COPY_TIMESTAMPS);
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);
video_width = filter->width;
g_cube_bits = filter->g_cube_bits;
@ -236,6 +236,9 @@ gst_dicetv_create_map (GstDiceTV * filter)
{
gint x, y, i;
if (filter->height <= 0 || filter->width <= 0)
return;
filter->g_map_height = filter->height >> filter->g_cube_bits;
filter->g_map_width = filter->width >> filter->g_cube_bits;
filter->g_cube_size = 1 << filter->g_cube_bits;
@ -255,17 +258,15 @@ static void
gst_dicetv_set_property (GObject * object, guint prop_id, const GValue * value,
GParamSpec * pspec)
{
GstDiceTV *filter;
g_return_if_fail (GST_IS_DICETV (object));
filter = GST_DICETV (object);
GstDiceTV *filter = GST_DICETV (object);
switch (prop_id) {
case ARG_CUBE_BITS:
filter->g_cube_bits = g_value_get_int (value);
gst_dicetv_create_map (filter);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
@ -274,11 +275,7 @@ static void
gst_dicetv_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstDiceTV *filter;
g_return_if_fail (GST_IS_DICETV (object));
filter = GST_DICETV (object);
GstDiceTV *filter = GST_DICETV (object);
switch (prop_id) {
case ARG_CUBE_BITS:
@ -290,12 +287,26 @@ gst_dicetv_get_property (GObject * object, guint prop_id, GValue * value,
}
}
static void
gst_dicetv_finalize (GObject * object)
{
GstDiceTV *filter = GST_DICETV (object);
g_free (filter->dicemap);
filter->dicemap = NULL;
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gst_dicetv_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (element_class, &gst_dicetv_details);
gst_element_class_set_details_simple (element_class, "DiceTV effect",
"Filter/Effect/Video",
"'Dices' the screen up into many small squares",
"Wim Taymans <wim.taymans@chello.be>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_dicetv_sink_template));
@ -304,22 +315,19 @@ gst_dicetv_base_init (gpointer g_class)
}
static void
gst_dicetv_class_init (gpointer klass, gpointer class_data)
gst_dicetv_class_init (GstDiceTVClass * klass)
{
GObjectClass *gobject_class;
GstBaseTransformClass *trans_class;
gobject_class = (GObjectClass *) klass;
trans_class = (GstBaseTransformClass *) klass;
parent_class = g_type_class_peek_parent (klass);
GObjectClass *gobject_class = (GObjectClass *) klass;
GstBaseTransformClass *trans_class = (GstBaseTransformClass *) klass;
gobject_class->set_property = gst_dicetv_set_property;
gobject_class->get_property = gst_dicetv_get_property;
gobject_class->finalize = gst_dicetv_finalize;
g_object_class_install_property (gobject_class, ARG_CUBE_BITS,
g_param_spec_int ("square_bits", "Square Bits", "The size of the Squares",
MIN_CUBE_BITS, MAX_CUBE_BITS, DEFAULT_CUBE_BITS, G_PARAM_READWRITE));
g_param_spec_int ("square-bits", "Square Bits", "The size of the Squares",
MIN_CUBE_BITS, MAX_CUBE_BITS, DEFAULT_CUBE_BITS,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_dicetv_set_caps);
trans_class->get_unit_size = GST_DEBUG_FUNCPTR (gst_dicetv_get_unit_size);
@ -327,38 +335,11 @@ gst_dicetv_class_init (gpointer klass, gpointer class_data)
}
static void
gst_dicetv_init (GTypeInstance * instance, gpointer g_class)
gst_dicetv_init (GstDiceTV * filter, GstDiceTVClass * klass)
{
GstDiceTV *filter = GST_DICETV (instance);
filter->dicemap = NULL;
filter->g_cube_bits = DEFAULT_CUBE_BITS;
filter->g_cube_size = 0;
filter->g_map_height = 0;
filter->g_map_width = 0;
}
GType
gst_dicetv_get_type (void)
{
static GType dicetv_type = 0;
if (!dicetv_type) {
static const GTypeInfo dicetv_info = {
sizeof (GstDiceTVClass),
gst_dicetv_base_init,
NULL,
(GClassInitFunc) gst_dicetv_class_init,
NULL,
NULL,
sizeof (GstDiceTV),
0,
(GInstanceInitFunc) gst_dicetv_init,
};
dicetv_type =
g_type_register_static (GST_TYPE_VIDEO_FILTER, "GstDiceTV",
&dicetv_info, 0);
}
return dicetv_type;
}