gstreamer/gst/effectv/gstdice.c
Julien Moutte 2ea4f5b3c9 VideoFilter inherits from
Original commit message from CVS:
2005-11-23  Julien MOUTTE  <julien@moutte.net>

* ext/cairo/gsttimeoverlay.c:
(gst_timeoverlay_update_font_height),
(gst_timeoverlay_set_caps), (gst_timeoverlay_get_unit_size),
(gst_timeoverlay_transform), (gst_timeoverlay_base_init),
(gst_timeoverlay_class_init), (gst_timeoverlay_init),
(gst_timeoverlay_get_type):
* ext/cairo/gsttimeoverlay.h:
* gst/debug/Makefile.am:
* gst/debug/gstnavigationtest.c:
(gst_navigationtest_handle_src_event),
(gst_navigationtest_get_unit_size),
(gst_navigationtest_set_caps),
(gst_navigationtest_transform),
(gst_navigationtest_change_state),
(gst_navigationtest_base_init), (gst_navigationtest_class_init),
(gst_navigationtest_init), (gst_navigationtest_get_type),
(plugin_init):
* gst/debug/gstnavigationtest.h:
* gst/effectv/Makefile.am:
* gst/effectv/gstaging.c: (gst_agingtv_set_caps),
(gst_agingtv_get_unit_size), (gst_agingtv_transform),
(gst_agingtv_base_init), (gst_agingtv_class_init),
(gst_agingtv_init), (gst_agingtv_get_type):
* gst/effectv/gstdice.c: (gst_dicetv_set_caps),
(gst_dicetv_get_unit_size), (gst_dicetv_transform),
(gst_dicetv_base_init), (gst_dicetv_class_init),
(gst_dicetv_init),
(gst_dicetv_get_type):
* gst/effectv/gstedge.c: (gst_edgetv_set_caps),
(gst_edgetv_get_unit_size), (gst_edgetv_transform),
(gst_edgetv_base_init), (gst_edgetv_class_init),
(gst_edgetv_init),
(gst_edgetv_get_type):
* gst/effectv/gsteffectv.c:
* gst/effectv/gsteffectv.h:
* gst/effectv/gstquark.c: (gst_quarktv_set_caps),
(gst_quarktv_get_unit_size), (fastrand),
(gst_quarktv_transform),
(gst_quarktv_change_state), (gst_quarktv_base_init),
(gst_quarktv_class_init), (gst_quarktv_init),
(gst_quarktv_get_type):
* gst/effectv/gstrev.c: (gst_revtv_set_caps),
(gst_revtv_get_unit_size), (gst_revtv_transform),
(gst_revtv_base_init), (gst_revtv_class_init), (gst_revtv_init),
(gst_revtv_get_type):
* gst/effectv/gstshagadelic.c: (gst_shagadelictv_set_caps),
(gst_shagadelictv_get_unit_size), (gst_shagadelictv_transform),
(gst_shagadelictv_base_init), (gst_shagadelictv_class_init),
(gst_shagadelictv_init), (gst_shagadelictv_get_type):
* gst/effectv/gstvertigo.c: (gst_vertigotv_set_caps),
(gst_vertigotv_get_unit_size), (gst_vertigotv_transform),
(gst_vertigotv_base_init), (gst_vertigotv_class_init),
(gst_vertigotv_init), (gst_vertigotv_get_type):
* gst/effectv/gstwarp.c: (gst_warptv_set_caps),
(gst_warptv_get_unit_size), (gst_warptv_transform),
(gst_warptv_base_init), (gst_warptv_class_init),
(gst_warptv_init),
(gst_warptv_get_type):
* gst/videofilter/Makefile.am:
* gst/videofilter/gstvideobalance.c:
* gst/videofilter/gstvideobalance.h:
* gst/videofilter/gstvideofilter.c: (gst_videofilter_get_type),
(gst_videofilter_class_init), (gst_videofilter_init):
* gst/videofilter/gstvideofilter.h:
* gst/videofilter/gstvideoflip.c: (gst_videoflip_set_caps),
(gst_videoflip_transform_caps), (gst_videoflip_get_unit_size),
(gst_videoflip_flip), (gst_videoflip_transform),
(gst_videoflip_handle_src_event), (gst_videoflip_set_property),
(gst_videoflip_base_init), (gst_videoflip_class_init),
(gst_videoflip_init), (plugin_init), (gst_videoflip_get_type):
* gst/videofilter/gstvideoflip.h: VideoFilter inherits from
BaseTransform, it's just a place holder for now and every video
effect plugin has been ported to use BaseTransform features
directly. QuarkTV was fixed too (was broken), navigationtest
works
and best for the end, videoflip converts navigation events
depending
on flip method ! Fixes #320953
2005-11-23 15:50:51 +00:00

365 lines
9.1 KiB
C

/* 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 Library 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gstvideofilter.h>
#include <string.h>
#include <gst/gst.h>
#include <gst/video/video.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_DICETV,GstDiceTVClass))
#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
{
GstVideofilter videofilter;
gint width, height;
gchar *dicemap;
gint g_cube_bits;
gint g_cube_size;
gint g_map_height;
gint g_map_width;
};
struct _GstDiceTVClass
{
GstVideofilterClass parent_class;
};
GType gst_dicetv_get_type (void);
static void gst_dicetv_create_map (GstDiceTV * filter);
static GstElementDetails gst_dicetv_details = GST_ELEMENT_DETAILS ("DiceTV",
"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,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_xRGB ";"
GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_xBGR)
);
static GstStaticPadTemplate gst_dicetv_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_xRGB ";"
GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_xBGR)
);
static GstVideofilterClass *parent_class = NULL;
enum
{
ARG_0,
ARG_CUBE_BITS
};
static gboolean
gst_dicetv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
GstCaps * outcaps)
{
GstDiceTV *filter = GST_DICETV (btrans);
GstStructure *structure;
gboolean ret = FALSE;
structure = gst_caps_get_structure (incaps, 0);
if (gst_structure_get_int (structure, "width", &filter->width) &&
gst_structure_get_int (structure, "height", &filter->height)) {
g_free (filter->dicemap);
filter->dicemap =
(gchar *) g_malloc (filter->height * filter->width * sizeof (char));
gst_dicetv_create_map (filter);
ret = TRUE;
}
return ret;
}
static gboolean
gst_dicetv_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
guint * size)
{
GstDiceTV *filter;
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) &&
gst_structure_get_int (structure, "height", &height)) {
*size = width * height * 32 / 8;
ret = TRUE;
GST_DEBUG_OBJECT (filter, "our frame size is %d bytes (%dx%d)", *size,
width, height);
}
return ret;
}
static unsigned int
fastrand (void)
{
static unsigned int fastrand_val;
return (fastrand_val = fastrand_val * 1103515245 + 12345);
}
static GstFlowReturn
gst_dicetv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
{
GstDiceTV *filter;
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;
filter = GST_DICETV (trans);
src = (guint32 *) GST_BUFFER_DATA (in);
dest = (guint32 *) GST_BUFFER_DATA (out);
gst_buffer_stamp (out, in);
video_width = filter->width;
g_cube_bits = filter->g_cube_bits;
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++;
}
}
return ret;
}
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_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);
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;
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;
}
}
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_add_pad_template (element_class,
gst_static_pad_template_get (&gst_dicetv_sink_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_dicetv_src_template));
}
static void
gst_dicetv_class_init (gpointer klass, gpointer class_data)
{
GObjectClass *gobject_class;
GstElementClass *element_class;
GstBaseTransformClass *trans_class;
gobject_class = (GObjectClass *) klass;
element_class = (GstElementClass *) klass;
trans_class = (GstBaseTransformClass *) klass;
parent_class = g_type_class_peek_parent (klass);
gobject_class->set_property = gst_dicetv_set_property;
gobject_class->get_property = gst_dicetv_get_property;
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));
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->transform = GST_DEBUG_FUNCPTR (gst_dicetv_transform);
}
static void
gst_dicetv_init (GTypeInstance * instance, gpointer g_class)
{
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_VIDEOFILTER, "GstDiceTV", &dicetv_info,
0);
}
return dicetv_type;
}