mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-12 18:35:35 +00:00
2ea4f5b3c9
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
365 lines
9.1 KiB
C
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;
|
|
}
|