mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-28 04:31:06 +00:00
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:
parent
d1ad31b9b3
commit
0cbdfcbc22
1 changed files with 50 additions and 69 deletions
|
@ -1,5 +1,6 @@
|
||||||
/* GStreamer
|
/* GStreamer
|
||||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
* 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
|
* dice.c: a 'dicing' effect
|
||||||
* copyright (c) 2001 Sam Mertens. This code is subject to the provisions of
|
* copyright (c) 2001 Sam Mertens. This code is subject to the provisions of
|
||||||
|
@ -14,12 +15,13 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <gst/video/gstvideofilter.h>
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
|
#include <gst/video/gstvideofilter.h>
|
||||||
|
|
||||||
|
#include <gst/controller/gstcontroller.h>
|
||||||
|
|
||||||
#define GST_TYPE_DICETV \
|
#define GST_TYPE_DICETV \
|
||||||
(gst_dicetv_get_type())
|
(gst_dicetv_get_type())
|
||||||
|
@ -66,16 +68,10 @@ struct _GstDiceTVClass
|
||||||
GstVideoFilterClass parent_class;
|
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 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 =
|
static GstStaticPadTemplate gst_dicetv_src_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("src",
|
GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_SRC,
|
GST_PAD_SRC,
|
||||||
|
@ -92,8 +88,6 @@ static GstStaticPadTemplate gst_dicetv_sink_template =
|
||||||
GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_xBGR)
|
GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_xBGR)
|
||||||
);
|
);
|
||||||
|
|
||||||
static GstVideoFilterClass *parent_class = NULL;
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ARG_0,
|
ARG_0,
|
||||||
|
@ -114,7 +108,7 @@ gst_dicetv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
|
||||||
gst_structure_get_int (structure, "height", &filter->height)) {
|
gst_structure_get_int (structure, "height", &filter->height)) {
|
||||||
g_free (filter->dicemap);
|
g_free (filter->dicemap);
|
||||||
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);
|
gst_dicetv_create_map (filter);
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -126,13 +120,11 @@ static gboolean
|
||||||
gst_dicetv_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
|
gst_dicetv_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
|
||||||
guint * size)
|
guint * size)
|
||||||
{
|
{
|
||||||
GstDiceTV *filter;
|
GstDiceTV *filter = GST_DICETV (btrans);
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
gint width, height;
|
gint width, height;
|
||||||
|
|
||||||
filter = GST_DICETV (btrans);
|
|
||||||
|
|
||||||
structure = gst_caps_get_structure (caps, 0);
|
structure = gst_caps_get_structure (caps, 0);
|
||||||
|
|
||||||
if (gst_structure_get_int (structure, "width", &width) &&
|
if (gst_structure_get_int (structure, "width", &width) &&
|
||||||
|
@ -146,10 +138,10 @@ gst_dicetv_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int
|
static inline guint
|
||||||
fastrand (void)
|
fastrand (void)
|
||||||
{
|
{
|
||||||
static unsigned int fastrand_val;
|
static guint fastrand_val;
|
||||||
|
|
||||||
return (fastrand_val = fastrand_val * 1103515245 + 12345);
|
return (fastrand_val = fastrand_val * 1103515245 + 12345);
|
||||||
}
|
}
|
||||||
|
@ -157,17 +149,25 @@ fastrand (void)
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_dicetv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
|
gst_dicetv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
|
||||||
{
|
{
|
||||||
GstDiceTV *filter;
|
GstDiceTV *filter = GST_DICETV (trans);
|
||||||
guint32 *src, *dest;
|
guint32 *src, *dest;
|
||||||
gint i, map_x, map_y, map_i, base, dx, dy, di;
|
gint i, map_x, map_y, map_i, base, dx, dy, di;
|
||||||
gint video_width, g_cube_bits, g_cube_size;
|
gint video_width, g_cube_bits, g_cube_size;
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
GstClockTime timestamp, stream_time;
|
||||||
|
|
||||||
filter = GST_DICETV (trans);
|
|
||||||
src = (guint32 *) GST_BUFFER_DATA (in);
|
src = (guint32 *) GST_BUFFER_DATA (in);
|
||||||
dest = (guint32 *) GST_BUFFER_DATA (out);
|
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;
|
video_width = filter->width;
|
||||||
g_cube_bits = filter->g_cube_bits;
|
g_cube_bits = filter->g_cube_bits;
|
||||||
|
@ -236,6 +236,9 @@ gst_dicetv_create_map (GstDiceTV * filter)
|
||||||
{
|
{
|
||||||
gint x, y, i;
|
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_height = filter->height >> filter->g_cube_bits;
|
||||||
filter->g_map_width = filter->width >> filter->g_cube_bits;
|
filter->g_map_width = filter->width >> filter->g_cube_bits;
|
||||||
filter->g_cube_size = 1 << 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,
|
gst_dicetv_set_property (GObject * object, guint prop_id, const GValue * value,
|
||||||
GParamSpec * pspec)
|
GParamSpec * pspec)
|
||||||
{
|
{
|
||||||
GstDiceTV *filter;
|
GstDiceTV *filter = GST_DICETV (object);
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_DICETV (object));
|
|
||||||
|
|
||||||
filter = GST_DICETV (object);
|
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case ARG_CUBE_BITS:
|
case ARG_CUBE_BITS:
|
||||||
filter->g_cube_bits = g_value_get_int (value);
|
filter->g_cube_bits = g_value_get_int (value);
|
||||||
gst_dicetv_create_map (filter);
|
gst_dicetv_create_map (filter);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -274,11 +275,7 @@ static void
|
||||||
gst_dicetv_get_property (GObject * object, guint prop_id, GValue * value,
|
gst_dicetv_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
GParamSpec * pspec)
|
GParamSpec * pspec)
|
||||||
{
|
{
|
||||||
GstDiceTV *filter;
|
GstDiceTV *filter = GST_DICETV (object);
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_DICETV (object));
|
|
||||||
|
|
||||||
filter = GST_DICETV (object);
|
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case ARG_CUBE_BITS:
|
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
|
static void
|
||||||
gst_dicetv_base_init (gpointer g_class)
|
gst_dicetv_base_init (gpointer g_class)
|
||||||
{
|
{
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (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_element_class_add_pad_template (element_class,
|
||||||
gst_static_pad_template_get (&gst_dicetv_sink_template));
|
gst_static_pad_template_get (&gst_dicetv_sink_template));
|
||||||
|
@ -304,22 +315,19 @@ gst_dicetv_base_init (gpointer g_class)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_dicetv_class_init (gpointer klass, gpointer class_data)
|
gst_dicetv_class_init (GstDiceTVClass * klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class;
|
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||||
GstBaseTransformClass *trans_class;
|
GstBaseTransformClass *trans_class = (GstBaseTransformClass *) klass;
|
||||||
|
|
||||||
gobject_class = (GObjectClass *) klass;
|
|
||||||
trans_class = (GstBaseTransformClass *) klass;
|
|
||||||
|
|
||||||
parent_class = g_type_class_peek_parent (klass);
|
|
||||||
|
|
||||||
gobject_class->set_property = gst_dicetv_set_property;
|
gobject_class->set_property = gst_dicetv_set_property;
|
||||||
gobject_class->get_property = gst_dicetv_get_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_object_class_install_property (gobject_class, ARG_CUBE_BITS,
|
||||||
g_param_spec_int ("square_bits", "Square Bits", "The size of the Squares",
|
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));
|
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->set_caps = GST_DEBUG_FUNCPTR (gst_dicetv_set_caps);
|
||||||
trans_class->get_unit_size = GST_DEBUG_FUNCPTR (gst_dicetv_get_unit_size);
|
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
|
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->dicemap = NULL;
|
||||||
filter->g_cube_bits = DEFAULT_CUBE_BITS;
|
filter->g_cube_bits = DEFAULT_CUBE_BITS;
|
||||||
filter->g_cube_size = 0;
|
filter->g_cube_size = 0;
|
||||||
filter->g_map_height = 0;
|
filter->g_map_height = 0;
|
||||||
filter->g_map_width = 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;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue