From 0cbdfcbc2252d10d7bf9fc3a9573f9d90f6db259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 15 Jun 2009 17:21:58 +0200 Subject: [PATCH] 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. --- gst/effectv/gstdice.c | 119 ++++++++++++++++++------------------------ 1 file changed, 50 insertions(+), 69 deletions(-) diff --git a/gst/effectv/gstdice.c b/gst/effectv/gstdice.c index 80fee6b4fc..f95bc4cdff 100644 --- a/gst/effectv/gstdice.c +++ b/gst/effectv/gstdice.c @@ -1,5 +1,6 @@ /* GStreamer * Copyright (C) <1999> Erik Walthinsen + * Copyright (C) <2009> Sebastian Dröge * * 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 - #include #include #include +#include + +#include #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 "); - 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 "); 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; -}