mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
Added the diceTV plugin
Original commit message from CVS: Added the diceTV plugin
This commit is contained in:
parent
f8f6dcc5a0
commit
20f880e4bc
5 changed files with 381 additions and 15 deletions
|
@ -2,7 +2,7 @@ plugindir = $(libdir)/gst
|
|||
|
||||
plugin_LTLIBRARIES = libgsteffectv.la
|
||||
|
||||
libgsteffectv_la_SOURCES = gsteffectv.c gstedge.c gstaging.c
|
||||
libgsteffectv_la_SOURCES = gsteffectv.c gstedge.c gstaging.c gstdice.c
|
||||
libgsteffectv_la_CFLAGS = $(GST_CFLAGS)
|
||||
libgsteffectv_la_LIBADD =
|
||||
libgsteffectv_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||
|
|
362
gst/effectv/gstdice.c
Normal file
362
gst/effectv/gstdice.c
Normal file
|
@ -0,0 +1,362 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||
*
|
||||
* dice.c: a 'dicing' effect
|
||||
* copyright (c) 2001 Sam Mertens. This code is subject to the provisions of
|
||||
* the GNU Public License.
|
||||
*
|
||||
* I suppose this looks similar to PuzzleTV, but it's not. The screen is
|
||||
* divided into small squares, each of which is rotated either 0, 90, 180 or
|
||||
* 270 degrees. The amount of rotation for each square is chosen at random.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <gst/gst.h>
|
||||
#include "gsteffectv.h"
|
||||
|
||||
#define GST_TYPE_DICETV \
|
||||
(gst_dicetv_get_type())
|
||||
#define GST_DICETV(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DICETV,GstDiceTV))
|
||||
#define GST_DICETV_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ULAW,GstDiceTV))
|
||||
#define GST_IS_DICETV(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DICETV))
|
||||
#define GST_IS_DICETV_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DICETV))
|
||||
|
||||
typedef struct _GstDiceTV GstDiceTV;
|
||||
typedef struct _GstDiceTVClass GstDiceTVClass;
|
||||
|
||||
#define DEFAULT_CUBE_BITS 4
|
||||
#define MAX_CUBE_BITS 5
|
||||
#define MIN_CUBE_BITS 0
|
||||
|
||||
typedef enum _dice_dir
|
||||
{
|
||||
DICE_UP = 0,
|
||||
DICE_RIGHT = 1,
|
||||
DICE_DOWN = 2,
|
||||
DICE_LEFT = 3
|
||||
} DiceDir;
|
||||
|
||||
struct _GstDiceTV
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
GstPad *sinkpad, *srcpad;
|
||||
|
||||
gint width, height;
|
||||
gchar* dicemap;
|
||||
|
||||
gint g_cube_bits;
|
||||
gint g_cube_size;
|
||||
gint g_map_height;
|
||||
gint g_map_width;
|
||||
};
|
||||
|
||||
struct _GstDiceTVClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
|
||||
void (*reset) (GstElement *elem);
|
||||
};
|
||||
|
||||
GstElementDetails gst_dicetv_details = {
|
||||
"DiceTV",
|
||||
"Filter/Effect",
|
||||
"'Dices' the screen up into many small squares",
|
||||
VERSION,
|
||||
"Wim Taymans <wim.taymans@chello.be>",
|
||||
"(c) 2001 Sam Mertens",
|
||||
};
|
||||
|
||||
|
||||
/* Filter signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
RESET_SIGNAL,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
ARG_CUBE_BITS,
|
||||
};
|
||||
|
||||
static void gst_dicetv_class_init (GstDiceTVClass * klass);
|
||||
static void gst_dicetv_init (GstDiceTV * filter);
|
||||
|
||||
static void gst_dicetv_reset_handler (GstElement *elem);
|
||||
static void gst_dicetv_create_map (GstDiceTV *filter);
|
||||
|
||||
static void gst_dicetv_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_dicetv_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static void gst_dicetv_chain (GstPad * pad, GstBuffer * buf);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
static guint gst_dicetv_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
GType gst_dicetv_get_type (void)
|
||||
{
|
||||
static GType dicetv_type = 0;
|
||||
|
||||
if (!dicetv_type) {
|
||||
static const GTypeInfo dicetv_info = {
|
||||
sizeof (GstDiceTVClass), NULL,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_dicetv_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstDiceTV),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_dicetv_init,
|
||||
};
|
||||
|
||||
dicetv_type = g_type_register_static (GST_TYPE_ELEMENT, "GstDiceTV", &dicetv_info, 0);
|
||||
}
|
||||
return dicetv_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dicetv_class_init (GstDiceTVClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
gst_dicetv_signals[RESET_SIGNAL] =
|
||||
g_signal_new ("reset",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstDiceTVClass, reset),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
klass->reset = gst_dicetv_reset_handler;
|
||||
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), 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));
|
||||
|
||||
gobject_class->set_property = gst_dicetv_set_property;
|
||||
gobject_class->get_property = gst_dicetv_get_property;
|
||||
}
|
||||
|
||||
static GstPadConnectReturn
|
||||
gst_dicetv_sinkconnect (GstPad * pad, GstCaps * caps)
|
||||
{
|
||||
GstDiceTV *filter;
|
||||
|
||||
filter = GST_DICETV (gst_pad_get_parent (pad));
|
||||
|
||||
if (!GST_CAPS_IS_FIXED (caps))
|
||||
return GST_PAD_CONNECT_DELAYED;
|
||||
|
||||
gst_caps_get_int (caps, "width", &filter->width);
|
||||
gst_caps_get_int (caps, "height", &filter->height);
|
||||
|
||||
g_free (filter->dicemap);
|
||||
filter->dicemap = (gchar *) g_malloc (filter->height * filter->width * sizeof(char));
|
||||
gst_dicetv_create_map (filter);
|
||||
|
||||
if (gst_pad_try_set_caps (filter->srcpad, caps)) {
|
||||
return GST_PAD_CONNECT_OK;
|
||||
}
|
||||
|
||||
return GST_PAD_CONNECT_REFUSED;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dicetv_init (GstDiceTV * filter)
|
||||
{
|
||||
filter->sinkpad = gst_pad_new_from_template (gst_effectv_sink_factory (), "sink");
|
||||
gst_pad_set_chain_function (filter->sinkpad, gst_dicetv_chain);
|
||||
gst_pad_set_connect_function (filter->sinkpad, gst_dicetv_sinkconnect);
|
||||
gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
|
||||
|
||||
filter->srcpad = gst_pad_new_from_template (gst_effectv_src_factory (), "src");
|
||||
gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dicetv_reset_handler (GstElement *elem)
|
||||
{
|
||||
GstDiceTV *filter = GST_DICETV (elem);
|
||||
|
||||
gst_dicetv_create_map (filter);
|
||||
}
|
||||
|
||||
|
||||
static unsigned int
|
||||
fastrand (void)
|
||||
{
|
||||
static unsigned int fastrand_val;
|
||||
|
||||
return (fastrand_val = fastrand_val * 1103515245 + 12345);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dicetv_draw (GstDiceTV *filter, guint32 *src, guint32 *dest)
|
||||
{
|
||||
gint i;
|
||||
gint map_x, map_y, map_i;
|
||||
gint base;
|
||||
gint dx, dy, di;
|
||||
gint video_width = filter->width;
|
||||
gint g_cube_bits = filter->g_cube_bits;
|
||||
gint g_cube_size = filter->g_cube_size;
|
||||
|
||||
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++) {
|
||||
base = (map_y << g_cube_bits) * video_width + (map_x << g_cube_bits);
|
||||
|
||||
switch (filter->dicemap[map_i]) {
|
||||
case DICE_UP:
|
||||
for (dy = 0; dy < g_cube_size; dy++) {
|
||||
i = base + dy * video_width;
|
||||
for (dx = 0; dx < g_cube_size; dx++) {
|
||||
dest[i] = src[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DICE_LEFT:
|
||||
for (dy = 0; dy < g_cube_size; dy++) {
|
||||
i = base + dy * video_width;
|
||||
|
||||
for (dx = 0; dx < g_cube_size; dx++) {
|
||||
di = base + (dx * video_width) + (g_cube_size - dy - 1);
|
||||
dest[di] = src[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DICE_DOWN:
|
||||
for (dy = 0; dy < g_cube_size; dy++) {
|
||||
di = base + dy * video_width;
|
||||
i = base + (g_cube_size - dy - 1) * video_width + g_cube_size;
|
||||
for (dx = 0; dx < g_cube_size; dx++) {
|
||||
i--;
|
||||
dest[di] = src[i];
|
||||
di++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DICE_RIGHT:
|
||||
for (dy = 0; dy < g_cube_size; dy++) {
|
||||
i = base + (dy * video_width);
|
||||
for (dx = 0; dx < g_cube_size; dx++) {
|
||||
di = base + dy + (g_cube_size - dx - 1) * video_width;
|
||||
dest[di] = src[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
map_i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dicetv_create_map (GstDiceTV *filter)
|
||||
{
|
||||
gint x, y, i;
|
||||
|
||||
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;
|
||||
|
||||
i = 0;
|
||||
|
||||
for (y = 0; y < filter->g_map_height; y++) {
|
||||
for(x = 0; x < filter->g_map_width; x++) {
|
||||
// dicemap[i] = ((i + y) & 0x3); /* Up, Down, Left or Right */
|
||||
filter->dicemap[i] = (fastrand() >> 24) & 0x03;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dicetv_chain (GstPad * pad, GstBuffer * buf)
|
||||
{
|
||||
GstDiceTV *filter;
|
||||
guint32 *src, *dest;
|
||||
GstBuffer *outbuf;
|
||||
|
||||
filter = GST_DICETV (gst_pad_get_parent (pad));
|
||||
|
||||
src = (guint32 *) GST_BUFFER_DATA (buf);
|
||||
|
||||
outbuf = gst_buffer_new ();
|
||||
GST_BUFFER_SIZE (outbuf) = (filter->width * filter->height * sizeof(guint32));
|
||||
dest = (guint32 *) GST_BUFFER_DATA (outbuf) = g_malloc (GST_BUFFER_SIZE (outbuf));
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
|
||||
|
||||
gst_dicetv_draw (filter, src, dest);
|
||||
|
||||
gst_buffer_unref (buf);
|
||||
|
||||
gst_pad_push (filter->srcpad, outbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dicetv_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstDiceTV *filter;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail (GST_IS_DICETV (object));
|
||||
|
||||
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);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dicetv_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstDiceTV *filter;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail (GST_IS_DICETV (object));
|
||||
|
||||
filter = GST_DICETV (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_CUBE_BITS:
|
||||
g_value_set_int (value, filter->g_cube_bits);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -17,16 +17,16 @@
|
|||
#include <gst/gst.h>
|
||||
#include "gsteffectv.h"
|
||||
|
||||
#define GST_TYPE_EFFECTV \
|
||||
#define GST_TYPE_EDGETV \
|
||||
(gst_edgetv_get_type())
|
||||
#define GST_EFFECTV(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_EFFECTV,GstEdgeTV))
|
||||
#define GST_EFFECTV_CLASS(klass) \
|
||||
#define GST_EDGETV(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_EDGETV,GstEdgeTV))
|
||||
#define GST_EDGETV_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ULAW,GstEdgeTV))
|
||||
#define GST_IS_EFFECTV(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_EFFECTV))
|
||||
#define GST_IS_EFFECTV_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_EFFECTV))
|
||||
#define GST_IS_EDGETV(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_EDGETV))
|
||||
#define GST_IS_EDGETV_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_EDGETV))
|
||||
|
||||
typedef struct _GstEdgeTV GstEdgeTV;
|
||||
typedef struct _GstEdgeTVClass GstEdgeTVClass;
|
||||
|
@ -125,7 +125,7 @@ gst_edgetv_sinkconnect (GstPad * pad, GstCaps * caps)
|
|||
{
|
||||
GstEdgeTV *filter;
|
||||
|
||||
filter = GST_EFFECTV (gst_pad_get_parent (pad));
|
||||
filter = GST_EDGETV (gst_pad_get_parent (pad));
|
||||
|
||||
if (!GST_CAPS_IS_FIXED (caps))
|
||||
return GST_PAD_CONNECT_DELAYED;
|
||||
|
@ -173,7 +173,7 @@ gst_edgetv_chain (GstPad * pad, GstBuffer * buf)
|
|||
guint32 v0, v1, v2, v3;
|
||||
GstBuffer *outbuf;
|
||||
|
||||
filter = GST_EFFECTV (gst_pad_get_parent (pad));
|
||||
filter = GST_EDGETV (gst_pad_get_parent (pad));
|
||||
|
||||
src = (guint32 *) GST_BUFFER_DATA (buf);
|
||||
|
||||
|
@ -270,9 +270,9 @@ gst_edgetv_set_property (GObject * object, guint prop_id, const GValue * value,
|
|||
GstEdgeTV *filter;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail (GST_IS_EFFECTV (object));
|
||||
g_return_if_fail (GST_IS_EDGETV (object));
|
||||
|
||||
filter = GST_EFFECTV (object);
|
||||
filter = GST_EDGETV (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
|
@ -286,9 +286,9 @@ gst_edgetv_get_property (GObject * object, guint prop_id, GValue * value, GParam
|
|||
GstEdgeTV *filter;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail (GST_IS_EFFECTV (object));
|
||||
g_return_if_fail (GST_IS_EDGETV (object));
|
||||
|
||||
filter = GST_EFFECTV (object);
|
||||
filter = GST_EDGETV (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
|
|
|
@ -28,6 +28,7 @@ struct _elements_entry {
|
|||
static struct _elements_entry _elements[] = {
|
||||
{ "edgeTV", gst_edgetv_get_type, &gst_edgetv_details, NULL },
|
||||
{ "agingTV", gst_agingtv_get_type, &gst_agingtv_details, NULL },
|
||||
{ "diceTV", gst_dicetv_get_type, &gst_dicetv_details, NULL },
|
||||
{ NULL, 0 },
|
||||
};
|
||||
|
||||
|
|
|
@ -21,5 +21,8 @@ extern GstElementDetails gst_edgetv_details;
|
|||
GType gst_agingtv_get_type (void);
|
||||
extern GstElementDetails gst_agingtv_details;
|
||||
|
||||
GType gst_dicetv_get_type (void);
|
||||
extern GstElementDetails gst_dicetv_details;
|
||||
|
||||
extern GstPadTemplate *gst_effectv_sink_factory ();
|
||||
extern GstPadTemplate *gst_effectv_src_factory ();
|
||||
|
|
Loading…
Reference in a new issue