summaryrefslogtreecommitdiffstats
path: root/gst/videofilter
diff options
context:
space:
mode:
authorJulien Moutte <julien@moutte.net>2005-11-23 15:50:51 +0000
committerJulien Moutte <julien@moutte.net>2005-11-23 15:50:51 +0000
commit2ea4f5b3c92819681f2d9e6f5f8d014b4d179344 (patch)
treedb8696ff4b83e3f0ea882402e3435d8dacdbb488 /gst/videofilter
parent48520a455d828b4a6885fb37be48ebb720ae259b (diff)
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
Diffstat (limited to 'gst/videofilter')
-rw-r--r--gst/videofilter/Makefile.am16
-rw-r--r--gst/videofilter/gstvideobalance.c12
-rw-r--r--gst/videofilter/gstvideobalance.h4
-rw-r--r--gst/videofilter/gstvideofilter.c484
-rw-r--r--gst/videofilter/gstvideofilter.h59
-rw-r--r--gst/videofilter/gstvideoflip.c613
-rw-r--r--gst/videofilter/gstvideoflip.h13
7 files changed, 413 insertions, 788 deletions
diff --git a/gst/videofilter/Makefile.am b/gst/videofilter/Makefile.am
index 2cc94db8..17b3c3fa 100644
--- a/gst/videofilter/Makefile.am
+++ b/gst/videofilter/Makefile.am
@@ -1,5 +1,5 @@
lib_LTLIBRARIES = libgstvideofilter-@GST_MAJORMINOR@.la
-noinst_LTLIBRARIES = libgstvideoexample.la
+# noinst_LTLIBRARIES = libgstvideoexample.la
plugin_LTLIBRARIES = libgstvideoflip.la
noinst_HEADERS = gstvideofilter.h gstvideoflip.h
@@ -11,14 +11,16 @@ libgstvideofilter_@GST_MAJORMINOR@_la_SOURCES = gstvideofilter.c gstvideofilter.
libgstvideofilter_@GST_MAJORMINOR@_la_CFLAGS = $(GST_CFLAGS)
libgstvideofilter_@GST_MAJORMINOR@_la_LDFLAGS = $(GST_LIBS)
-libgstvideoexample_la_SOURCES = gstvideoexample.c
-libgstvideoexample_la_CFLAGS = $(GST_CFLAGS)
-libgstvideoexample_la_LIBADD = libgstvideofilter-@GST_MAJORMINOR@.la $(GST_LIBS)
-libgstvideoexample_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+# libgstvideoexample_la_SOURCES = gstvideoexample.c
+# libgstvideoexample_la_CFLAGS = $(GST_CFLAGS)
+# libgstvideoexample_la_LIBADD = libgstvideofilter-@GST_MAJORMINOR@.la $(GST_LIBS)
+# libgstvideoexample_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstvideoflip_la_SOURCES = gstvideoflip.c
-libgstvideoflip_la_CFLAGS = $(GST_CFLAGS)
-libgstvideoflip_la_LIBADD = libgstvideofilter-@GST_MAJORMINOR@.la $(GST_LIBS)
+libgstvideoflip_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) \
+ $(GST_PLUGINS_BASE_CFLAGS)
+libgstvideoflip_la_LIBADD = libgstvideofilter-@GST_MAJORMINOR@.la $(GST_LIBS) \
+ $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS)
libgstvideoflip_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
# libgstvideobalance_la_SOURCES = gstvideobalance.c
diff --git a/gst/videofilter/gstvideobalance.c b/gst/videofilter/gstvideobalance.c
index 0825aa46..919f13ff 100644
--- a/gst/videofilter/gstvideobalance.c
+++ b/gst/videofilter/gstvideobalance.c
@@ -27,7 +27,6 @@
#include "config.h"
#endif
-/*#define DEBUG_ENABLED */
#include "gstvideobalance.h"
#ifdef HAVE_LIBOIL
#include <liboil/liboil.h>
@@ -40,12 +39,6 @@
/* GstVideobalance signals and args */
enum
{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
-{
ARG_0,
ARG_CONTRAST,
ARG_BRIGHTNESS,
@@ -117,11 +110,6 @@ gst_videobalance_get_type (void)
return videobalance_type;
}
-static GstVideofilterFormat gst_videobalance_formats[] = {
- {"I420", 12, gst_videobalance_planar411,},
-};
-
-
static void
gst_videobalance_base_init (gpointer g_class)
{
diff --git a/gst/videofilter/gstvideobalance.h b/gst/videofilter/gstvideobalance.h
index 45aab910..ac709f88 100644
--- a/gst/videofilter/gstvideobalance.h
+++ b/gst/videofilter/gstvideobalance.h
@@ -21,12 +21,8 @@
#ifndef __GST_VIDEOBALANCE_H__
#define __GST_VIDEOBALANCE_H__
-
-#include <gst/gst.h>
-
#include "gstvideofilter.h"
-
G_BEGIN_DECLS
#define GST_TYPE_VIDEOBALANCE \
diff --git a/gst/videofilter/gstvideofilter.c b/gst/videofilter/gstvideofilter.c
index 89951bb9..a7d9db0e 100644
--- a/gst/videofilter/gstvideofilter.c
+++ b/gst/videofilter/gstvideofilter.c
@@ -22,40 +22,15 @@
#include "config.h"
#endif
-#include <string.h>
-/*#define DEBUG_ENABLED */
#include "gstvideofilter.h"
GST_DEBUG_CATEGORY_STATIC (gst_videofilter_debug);
#define GST_CAT_DEFAULT gst_videofilter_debug
-/* GstVideofilter signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
-{
- ARG_0,
- ARG_METHOD
- /* FILL ME */
-};
-
-static void gst_videofilter_base_init (gpointer g_class);
static void gst_videofilter_class_init (gpointer g_class, gpointer class_data);
static void gst_videofilter_init (GTypeInstance * instance, gpointer g_class);
-static void gst_videofilter_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_videofilter_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-static GstFlowReturn gst_videofilter_chain (GstPad * pad, GstBuffer * buffer);
-GstCaps *gst_videofilter_class_get_capslist (GstVideofilterClass * klass);
-
-static GstElementClass *parent_class = NULL;
+static GstBaseTransformClass *parent_class = NULL;
GType
gst_videofilter_get_type (void)
@@ -65,7 +40,7 @@ gst_videofilter_get_type (void)
if (!videofilter_type) {
static const GTypeInfo videofilter_info = {
sizeof (GstVideofilterClass),
- gst_videofilter_base_init,
+ NULL,
NULL,
gst_videofilter_class_init,
NULL,
@@ -75,484 +50,37 @@ gst_videofilter_get_type (void)
gst_videofilter_init,
};
- videofilter_type = g_type_register_static (GST_TYPE_ELEMENT,
+ videofilter_type = g_type_register_static (GST_TYPE_BASE_TRANSFORM,
"GstVideofilter", &videofilter_info, G_TYPE_FLAG_ABSTRACT);
}
return videofilter_type;
}
static void
-gst_videofilter_base_init (gpointer g_class)
-{
- static GstElementDetails videofilter_details = {
- "Video scaler",
- "Filter/Effect/Video",
- "Resizes video",
- "David Schleef <ds@schleef.org>"
- };
- GstVideofilterClass *klass = (GstVideofilterClass *) g_class;
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- klass->formats = g_ptr_array_new ();
-
- gst_element_class_set_details (element_class, &videofilter_details);
-}
-
-static void
gst_videofilter_class_init (gpointer g_class, gpointer class_data)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
+ GstBaseTransformClass *trans_class;
GstVideofilterClass *klass;
klass = (GstVideofilterClass *) g_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
+ trans_class = (GstBaseTransformClass *) klass;
- parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
-
- gobject_class->set_property = gst_videofilter_set_property;
- gobject_class->get_property = gst_videofilter_get_property;
+ parent_class = g_type_class_peek_parent (klass);
GST_DEBUG_CATEGORY_INIT (gst_videofilter_debug, "videofilter", 0,
"videofilter");
}
-static GstStructure *
-gst_videofilter_format_get_structure (GstVideofilterFormat * format)
-{
- unsigned int fourcc;
- GstStructure *structure;
-
- if (format->filter_func == NULL)
- return NULL;
-
- fourcc =
- GST_MAKE_FOURCC (format->fourcc[0], format->fourcc[1], format->fourcc[2],
- format->fourcc[3]);
-
- if (format->depth) {
- structure = gst_structure_new ("video/x-raw-rgb",
- "depth", G_TYPE_INT, format->depth,
- "bpp", G_TYPE_INT, format->bpp,
- "endianness", G_TYPE_INT, format->endianness,
- "red_mask", G_TYPE_INT, format->red_mask,
- "green_mask", G_TYPE_INT, format->green_mask,
- "blue_mask", G_TYPE_INT, format->blue_mask, NULL);
- } else {
- structure = gst_structure_new ("video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, fourcc, NULL);
- }
-
- gst_structure_set (structure,
- "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
- "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
- "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
-
- return structure;
-}
-
-GstCaps *
-gst_videofilter_class_get_capslist (GstVideofilterClass * klass)
-{
- GstCaps *caps;
- GstStructure *structure;
- int i;
-
- caps = gst_caps_new_empty ();
- for (i = 0; i < klass->formats->len; i++) {
- structure =
- gst_videofilter_format_get_structure (g_ptr_array_index (klass->formats,
- i));
- gst_caps_append_structure (caps, structure);
- }
-
- return caps;
-}
-
-static GstCaps *
-gst_videofilter_getcaps (GstPad * pad)
-{
- GstVideofilter *videofilter;
- GstVideofilterClass *klass;
- GstCaps *caps;
- GstPad *peer;
- int i;
-
- videofilter = GST_VIDEOFILTER (GST_PAD_PARENT (pad));
- GST_DEBUG_OBJECT (videofilter, "gst_videofilter_getcaps");
-
- klass = GST_VIDEOFILTER_CLASS (G_OBJECT_GET_CLASS (videofilter));
-
- /* we can handle anything that was registered */
- caps = gst_caps_new_empty ();
- for (i = 0; i < klass->formats->len; i++) {
- GstCaps *fromcaps;
-
- fromcaps =
- gst_caps_new_full (gst_videofilter_format_get_structure
- (g_ptr_array_index (klass->formats, i)), NULL);
-
- gst_caps_append (caps, fromcaps);
- }
-
- peer = gst_pad_get_peer (pad);
- if (peer) {
- GstCaps *peercaps;
-
- peercaps = gst_pad_get_caps (peer);
- if (peercaps) {
- GstCaps *icaps;
-
- icaps = gst_caps_intersect (peercaps, caps);
- gst_caps_unref (peercaps);
- gst_caps_unref (caps);
- caps = icaps;
- }
- //gst_object_unref (peer);
- }
-
- return caps;
-}
-
-static gboolean
-gst_videofilter_setcaps (GstPad * pad, GstCaps * caps)
-{
- GstVideofilter *videofilter;
- GstStructure *structure;
- int width, height;
- const GValue *framerate;
- int ret;
-
- videofilter = GST_VIDEOFILTER (GST_PAD_PARENT (pad));
-
- structure = gst_caps_get_structure (caps, 0);
-
- videofilter->format =
- gst_videofilter_find_format_by_structure (videofilter, structure);
- g_return_val_if_fail (videofilter->format, GST_PAD_LINK_REFUSED);
-
- ret = gst_structure_get_int (structure, "width", &width);
- ret &= gst_structure_get_int (structure, "height", &height);
-
- framerate = gst_structure_get_value (structure, "framerate");
- ret &= (framerate != NULL && GST_VALUE_HOLDS_FRACTION (framerate));
-
- if (!ret)
- return FALSE;
-
- gst_pad_set_caps (videofilter->srcpad, caps);
-
- GST_DEBUG_OBJECT (videofilter, "width %d height %d", width, height);
-
-#if 0
- if (pad == videofilter->srcpad) {
- videofilter->to_width = width;
- videofilter->to_height = height;
- } else {
- videofilter->from_width = width;
- videofilter->from_height = height;
- }
-#endif
- videofilter->to_width = width;
- videofilter->to_height = height;
- videofilter->from_width = width;
- videofilter->from_height = height;
- g_value_copy (framerate, &videofilter->framerate);
-
- gst_videofilter_setup (videofilter);
-
- return TRUE;
-}
-
static void
gst_videofilter_init (GTypeInstance * instance, gpointer g_class)
{
GstVideofilter *videofilter = GST_VIDEOFILTER (instance);
- GstPadTemplate *pad_template;
GST_DEBUG_OBJECT (videofilter, "gst_videofilter_init");
- pad_template =
- gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink");
- g_return_if_fail (pad_template != NULL);
- videofilter->sinkpad = gst_pad_new_from_template (pad_template, "sink");
- gst_element_add_pad (GST_ELEMENT (videofilter), videofilter->sinkpad);
- gst_pad_set_chain_function (videofilter->sinkpad, gst_videofilter_chain);
- gst_pad_set_setcaps_function (videofilter->sinkpad, gst_videofilter_setcaps);
- gst_pad_set_getcaps_function (videofilter->sinkpad, gst_videofilter_getcaps);
-
- pad_template =
- gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
- g_return_if_fail (pad_template != NULL);
- videofilter->srcpad = gst_pad_new_from_template (pad_template, "src");
- gst_element_add_pad (GST_ELEMENT (videofilter), videofilter->srcpad);
- gst_pad_set_getcaps_function (videofilter->srcpad, gst_videofilter_getcaps);
-
videofilter->inited = FALSE;
- g_value_init (&videofilter->framerate, GST_TYPE_FRACTION);
-}
-
-static GstFlowReturn
-gst_videofilter_chain (GstPad * pad, GstBuffer * buf)
-{
- GstVideofilter *videofilter;
- guchar *data;
- gulong size;
- GstBuffer *outbuf;
- GstFlowReturn ret;
-
- videofilter = GST_VIDEOFILTER (GST_PAD_PARENT (pad));
- GST_DEBUG_OBJECT (videofilter, "gst_videofilter_chain");
-
- if (videofilter->passthru) {
- return gst_pad_push (videofilter->srcpad, buf);
- }
-
- if (GST_PAD_CAPS (pad) == NULL) {
- return GST_FLOW_NOT_NEGOTIATED;
- }
-
- data = GST_BUFFER_DATA (buf);
- size = GST_BUFFER_SIZE (buf);
-
- GST_LOG_OBJECT (videofilter, "got buffer of %ld bytes in '%s'", size,
- GST_OBJECT_NAME (videofilter));
-
- GST_LOG_OBJECT (videofilter,
- "size=%ld from=%dx%d to=%dx%d fromsize=%ld (should be %d) tosize=%d",
- size, videofilter->from_width, videofilter->from_height,
- videofilter->to_width, videofilter->to_height, size,
- videofilter->from_buf_size, videofilter->to_buf_size);
-
-
- if (size > videofilter->from_buf_size) {
- GST_INFO_OBJECT (videofilter, "buffer size %ld larger than expected (%d)",
- size, videofilter->from_buf_size);
- return GST_FLOW_ERROR;
- }
-
- ret = gst_pad_alloc_buffer (videofilter->srcpad, GST_BUFFER_OFFSET_NONE,
- videofilter->to_buf_size, GST_PAD_CAPS (videofilter->srcpad), &outbuf);
- if (ret != GST_FLOW_OK)
- goto no_buffer;
-
- g_return_val_if_fail (GST_BUFFER_DATA (outbuf), GST_FLOW_ERROR);
-
- GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
- GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
-
- g_return_val_if_fail (videofilter->format, GST_FLOW_ERROR);
- GST_DEBUG_OBJECT (videofilter, "format %s", videofilter->format->fourcc);
-
- videofilter->in_buf = buf;
- videofilter->out_buf = outbuf;
-
- videofilter->format->filter_func (videofilter, GST_BUFFER_DATA (outbuf),
- data);
- gst_buffer_unref (buf);
-
- GST_LOG_OBJECT (videofilter, "pushing buffer of %d bytes in '%s'",
- GST_BUFFER_SIZE (outbuf), GST_OBJECT_NAME (videofilter));
-
- ret = gst_pad_push (videofilter->srcpad, outbuf);
-
- return ret;
-
-no_buffer:
- {
- return ret;
- }
-}
-
-static void
-gst_videofilter_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstVideofilter *videofilter;
-
- g_return_if_fail (GST_IS_VIDEOFILTER (object));
- videofilter = GST_VIDEOFILTER (object);
-
- GST_DEBUG_OBJECT (videofilter, "gst_videofilter_set_property");
- switch (prop_id) {
- default:
- break;
- }
-}
-
-static void
-gst_videofilter_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstVideofilter *videofilter;
-
- g_return_if_fail (GST_IS_VIDEOFILTER (object));
- videofilter = GST_VIDEOFILTER (object);
-
- switch (prop_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-int
-gst_videofilter_get_input_width (GstVideofilter * videofilter)
-{
- g_return_val_if_fail (GST_IS_VIDEOFILTER (videofilter), 0);
-
- return videofilter->from_width;
-}
-
-int
-gst_videofilter_get_input_height (GstVideofilter * videofilter)
-{
- g_return_val_if_fail (GST_IS_VIDEOFILTER (videofilter), 0);
-
- return videofilter->from_height;
-}
-
-void
-gst_videofilter_set_output_size (GstVideofilter * videofilter,
- int width, int height)
-{
- GstCaps *srccaps;
- GstStructure *structure;
-
- g_return_if_fail (GST_IS_VIDEOFILTER (videofilter));
-
- videofilter->to_width = width;
- videofilter->to_height = height;
-
- videofilter->to_buf_size = (videofilter->to_width * videofilter->to_height
- * videofilter->format->bpp) / 8;
-
- //srccaps = gst_caps_copy (gst_pad_get_negotiated_caps (videofilter->srcpad));
- srccaps = gst_caps_copy (GST_PAD_CAPS (videofilter->srcpad));
- structure = gst_caps_get_structure (srccaps, 0);
-
- gst_structure_set (structure, "width", G_TYPE_INT, width,
- "height", G_TYPE_INT, height, NULL);
-
- gst_pad_set_caps (videofilter->srcpad, srccaps);
-}
-
-void
-gst_videofilter_setup (GstVideofilter * videofilter)
-{
- GstVideofilterClass *klass;
-
- GST_DEBUG_OBJECT (videofilter, "setup");
-
- klass = GST_VIDEOFILTER_CLASS (G_OBJECT_GET_CLASS (videofilter));
-
- if (klass->setup) {
- GST_DEBUG_OBJECT (videofilter, "calling class setup method");
- klass->setup (videofilter);
- }
-
- if (videofilter->to_width == 0) {
- videofilter->to_width = videofilter->from_width;
- }
- if (videofilter->to_height == 0) {
- videofilter->to_height = videofilter->from_height;
- }
-
- g_return_if_fail (videofilter->format != NULL);
- g_return_if_fail (videofilter->from_width > 0);
- g_return_if_fail (videofilter->from_height > 0);
- g_return_if_fail (videofilter->to_width > 0);
- g_return_if_fail (videofilter->to_height > 0);
-
- videofilter->from_buf_size =
- (videofilter->from_width * videofilter->from_height *
- videofilter->format->bpp) / 8;
- videofilter->to_buf_size =
- (videofilter->to_width * videofilter->to_height *
- videofilter->format->bpp) / 8;
-
- GST_DEBUG_OBJECT (videofilter, "from_buf_size %d to_buf_size %d",
- videofilter->from_buf_size, videofilter->to_buf_size);
- videofilter->inited = TRUE;
-}
-
-GstVideofilterFormat *
-gst_videofilter_find_format_by_structure (GstVideofilter * videofilter,
- const GstStructure * structure)
-{
- int i;
- GstVideofilterClass *klass;
- GstVideofilterFormat *format;
- gboolean ret;
-
- klass = GST_VIDEOFILTER_CLASS (G_OBJECT_GET_CLASS (videofilter));
-
- g_return_val_if_fail (structure != NULL, NULL);
-
- if (strcmp (gst_structure_get_name (structure), "video/x-raw-yuv") == 0) {
- guint32 fourcc;
-
- ret = gst_structure_get_fourcc (structure, "format", &fourcc);
- if (!ret)
- return NULL;
- for (i = 0; i < klass->formats->len; i++) {
- guint32 format_fourcc;
-
- format = g_ptr_array_index (klass->formats, i);
- format_fourcc = GST_STR_FOURCC (format->fourcc);
- if (format->depth == 0 && format_fourcc == fourcc) {
- return format;
- }
- }
- } else if (strcmp (gst_structure_get_name (structure), "video/x-raw-rgb")
- == 0) {
- int bpp;
- int depth;
- int endianness;
- int red_mask;
- int green_mask;
- int blue_mask;
-
- ret = gst_structure_get_int (structure, "bpp", &bpp);
- ret &= gst_structure_get_int (structure, "depth", &depth);
- ret &= gst_structure_get_int (structure, "endianness", &endianness);
- ret &= gst_structure_get_int (structure, "red_mask", &red_mask);
- ret &= gst_structure_get_int (structure, "green_mask", &green_mask);
- ret &= gst_structure_get_int (structure, "blue_mask", &blue_mask);
- if (!ret)
- return NULL;
- for (i = 0; i < klass->formats->len; i++) {
- format = g_ptr_array_index (klass->formats, i);
- if (format->bpp == bpp && format->depth == depth &&
- format->endianness == endianness && format->red_mask == red_mask &&
- format->green_mask == green_mask && format->blue_mask == blue_mask) {
- return format;
- }
- }
- }
-
- return NULL;
-}
-
-void
-gst_videofilter_class_add_format (GstVideofilterClass * videofilterclass,
- GstVideofilterFormat * format)
-{
- g_ptr_array_add (videofilterclass->formats, format);
-}
-
-void
-gst_videofilter_class_add_pad_templates (GstVideofilterClass *
- videofilter_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (videofilter_class);
-
- gst_element_class_add_pad_template (element_class,
- gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
- gst_videofilter_class_get_capslist (videofilter_class)));
-
- gst_element_class_add_pad_template (element_class,
- gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
- gst_videofilter_class_get_capslist (videofilter_class)));
}
diff --git a/gst/videofilter/gstvideofilter.h b/gst/videofilter/gstvideofilter.h
index 9923a2a7..a2f9ef04 100644
--- a/gst/videofilter/gstvideofilter.h
+++ b/gst/videofilter/gstvideofilter.h
@@ -21,32 +21,13 @@
#ifndef __GST_VIDEOFILTER_H__
#define __GST_VIDEOFILTER_H__
-
-#include <gst/gst.h>
-
+#include <gst/base/gstbasetransform.h>
G_BEGIN_DECLS
typedef struct _GstVideofilter GstVideofilter;
typedef struct _GstVideofilterClass GstVideofilterClass;
-typedef void (*GstVideofilterFilterFunc)(GstVideofilter *filter,
- void *out_data, void *in_data);
-
-typedef void (*GstVideofilterSetupFunc)(GstVideofilter *filter);
-
-typedef struct _GstVideofilterFormat GstVideofilterFormat;
-struct _GstVideofilterFormat {
- char *fourcc;
- int bpp;
- GstVideofilterFilterFunc filter_func;
- int depth;
- unsigned int endianness;
- unsigned int red_mask;
- unsigned int green_mask;
- unsigned int blue_mask;
-};
-
#define GST_TYPE_VIDEOFILTER \
(gst_videofilter_get_type())
#define GST_VIDEOFILTER(obj) \
@@ -59,51 +40,17 @@ struct _GstVideofilterFormat {
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VIDEOFILTER))
struct _GstVideofilter {
- GstElement element;
-
- GstPad *sinkpad,*srcpad;
+ GstBaseTransform element;
- /* video state */
gboolean inited;
- GstVideofilterFormat *format;
- gint to_width;
- gint to_height;
- gint from_width;
- gint from_height;
- gboolean passthru;
-
- /* private */
- gint from_buf_size;
- gint to_buf_size;
- GValue framerate;
-
- GstBuffer *in_buf;
- GstBuffer *out_buf;
};
struct _GstVideofilterClass {
- GstElementClass parent_class;
-
- GPtrArray *formats;
- GstVideofilterSetupFunc setup;
+ GstBaseTransformClass parent_class;
};
GType gst_videofilter_get_type(void);
-int gst_videofilter_get_input_width(GstVideofilter *videofilter);
-int gst_videofilter_get_input_height(GstVideofilter *videofilter);
-void gst_videofilter_set_output_size(GstVideofilter *videofilter,
- int width, int height);
-GstVideofilterFormat *gst_videofilter_find_format_by_structure (GstVideofilter *filter,
- const GstStructure *structure);
-GstCaps *gst_videofilter_class_get_capslist(GstVideofilterClass *videofilterclass);
-void gst_videofilter_setup (GstVideofilter * videofilter);
-
-void gst_videofilter_class_add_format(GstVideofilterClass *videofilterclass,
- GstVideofilterFormat *format);
-void gst_videofilter_class_add_pad_templates (GstVideofilterClass *videofilterclass);
-
G_END_DECLS
#endif /* __GST_VIDEOFILTER_H__ */
-
diff --git a/gst/videofilter/gstvideoflip.c b/gst/videofilter/gstvideoflip.c
index da9a76b9..d0f3263e 100644
--- a/gst/videofilter/gstvideoflip.c
+++ b/gst/videofilter/gstvideoflip.c
@@ -27,17 +27,11 @@
#include "config.h"
#endif
-/*#define DEBUG_ENABLED */
#include "gstvideoflip.h"
-#include <string.h>
-/* GstVideoflip signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
+#include <gst/video/video.h>
+/* GstVideoflip signals and args */
enum
{
ARG_0,
@@ -45,21 +39,30 @@ enum
/* FILL ME */
};
-GST_DEBUG_CATEGORY_STATIC (gst_videoflip_debug);
-#define GST_CAT_DEFAULT gst_videoflip_debug
+GST_DEBUG_CATEGORY (videoflip_debug);
+#define GST_CAT_DEFAULT videoflip_debug
-static void gst_videoflip_base_init (gpointer g_class);
-static void gst_videoflip_class_init (gpointer g_class, gpointer class_data);
-static void gst_videoflip_init (GTypeInstance * instance, gpointer g_class);
+static GstElementDetails videoflip_details =
+GST_ELEMENT_DETAILS ("Video Flipper",
+ "Filter/Effect/Video",
+ "Flips and rotates video",
+ "David Schleef <ds@schleef.org>");
+
+static GstStaticPadTemplate gst_videoflip_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ IYUV, I420, YV12 }"))
+ );
-static void gst_videoflip_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_videoflip_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
+static GstStaticPadTemplate gst_videoflip_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ IYUV, I420, YV12 }"))
+ );
-static void gst_videoflip_planar411 (GstVideofilter * videofilter, void *dest,
- void *src);
-static void gst_videoflip_setup (GstVideofilter * videofilter);
+static GstVideofilterClass *parent_class = NULL;
#define GST_TYPE_VIDEOFLIP_METHOD (gst_videoflip_method_get_type())
@@ -72,7 +75,7 @@ gst_videoflip_method_get_type (void)
{GST_VIDEOFLIP_METHOD_90R, "Rotate clockwise 90 degrees", "clockwise"},
{GST_VIDEOFLIP_METHOD_180, "Rotate 180 degrees", "rotate-180"},
{GST_VIDEOFLIP_METHOD_90L, "Rotate counter-clockwise 90 degrees",
- "counterclockwise"},
+ "counterclockwise"},
{GST_VIDEOFLIP_METHOD_HORIZ, "Flip horizontally", "horizontal-flip"},
{GST_VIDEOFLIP_METHOD_VERT, "Flip vertically", "vertical-flip"},
{GST_VIDEOFLIP_METHOD_TRANS,
@@ -89,90 +92,318 @@ gst_videoflip_method_get_type (void)
return videoflip_method_type;
}
-GType
-gst_videoflip_get_type (void)
+static gboolean
+gst_videoflip_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
+ GstCaps * outcaps)
{
- static GType videoflip_type = 0;
+ GstVideoflip *vf;
+ GstStructure *in_s, *out_s;
+ gboolean ret = FALSE;
+
+ vf = GST_VIDEOFLIP (btrans);
+
+ in_s = gst_caps_get_structure (incaps, 0);
+ out_s = gst_caps_get_structure (outcaps, 0);
+
+ if (gst_structure_get_int (in_s, "width", &vf->from_width) &&
+ gst_structure_get_int (in_s, "height", &vf->from_height) &&
+ gst_structure_get_int (out_s, "width", &vf->to_width) &&
+ gst_structure_get_int (out_s, "height", &vf->to_height)) {
+ /* Check that they are correct */
+ switch (vf->method) {
+ case GST_VIDEOFLIP_METHOD_90R:
+ case GST_VIDEOFLIP_METHOD_90L:
+ case GST_VIDEOFLIP_METHOD_TRANS:
+ case GST_VIDEOFLIP_METHOD_OTHER:
+ if ((vf->from_width != vf->to_height) ||
+ (vf->from_height != vf->to_width)) {
+ GST_DEBUG_OBJECT (vf, "we are inverting width and height but caps "
+ "are not correct : %dx%d to %dx%d", vf->from_width,
+ vf->from_height, vf->to_width, vf->to_height);
+ goto beach;
+ }
+ break;
+ case GST_VIDEOFLIP_METHOD_IDENTITY:
+
+ break;
+ case GST_VIDEOFLIP_METHOD_180:
+ case GST_VIDEOFLIP_METHOD_HORIZ:
+ case GST_VIDEOFLIP_METHOD_VERT:
+ if ((vf->from_width != vf->to_width) ||
+ (vf->from_height != vf->to_height)) {
+ GST_DEBUG_OBJECT (vf, "we are keeping width and height but caps "
+ "are not correct : %dx%d to %dx%d", vf->from_width,
+ vf->from_height, vf->to_width, vf->to_height);
+ goto beach;
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ }
- if (!videoflip_type) {
- static const GTypeInfo videoflip_info = {
- sizeof (GstVideoflipClass),
- gst_videoflip_base_init,
- NULL,
- gst_videoflip_class_init,
- NULL,
- NULL,
- sizeof (GstVideoflip),
- 0,
- gst_videoflip_init,
- };
+ ret = TRUE;
- videoflip_type = g_type_register_static (GST_TYPE_VIDEOFILTER,
- "GstVideoflip", &videoflip_info, 0);
+beach:
+ return ret;
+}
+
+static GstCaps *
+gst_videoflip_transform_caps (GstBaseTransform * trans,
+ GstPadDirection direction, GstCaps * caps)
+{
+ GstVideoflip *videoflip;
+ GstCaps *ret;
+ gint width, height, i;
+
+ videoflip = GST_VIDEOFLIP (trans);
+
+ ret = gst_caps_copy (caps);
+
+ for (i = 0; i < gst_caps_get_size (ret); i++) {
+ GstStructure *structure = gst_caps_get_structure (ret, i);
+
+ if (gst_structure_get_int (structure, "width", &width) &&
+ gst_structure_get_int (structure, "height", &height)) {
+
+ switch (videoflip->method) {
+ case GST_VIDEOFLIP_METHOD_90R:
+ case GST_VIDEOFLIP_METHOD_90L:
+ case GST_VIDEOFLIP_METHOD_TRANS:
+ case GST_VIDEOFLIP_METHOD_OTHER:
+ gst_structure_set (structure, "width", G_TYPE_INT, height,
+ "height", G_TYPE_INT, width, NULL);
+ break;
+ case GST_VIDEOFLIP_METHOD_IDENTITY:
+ case GST_VIDEOFLIP_METHOD_180:
+ case GST_VIDEOFLIP_METHOD_HORIZ:
+ case GST_VIDEOFLIP_METHOD_VERT:
+ gst_structure_set (structure, "width", G_TYPE_INT, width,
+ "height", G_TYPE_INT, height, NULL);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ }
}
- return videoflip_type;
+
+ GST_DEBUG_OBJECT (videoflip, "transformed %" GST_PTR_FORMAT " to %"
+ GST_PTR_FORMAT, caps, ret);
+
+ return ret;
}
-static GstVideofilterFormat gst_videoflip_formats[] = {
- /* planar */
- {"YV12", 12, gst_videoflip_planar411,},
- {"I420", 12, gst_videoflip_planar411,},
- {"IYUV", 12, gst_videoflip_planar411,},
-};
+/* Useful macros */
+#define GST_VIDEO_I420_Y_ROWSTRIDE(width) (GST_ROUND_UP_4(width))
+#define GST_VIDEO_I420_U_ROWSTRIDE(width) (GST_ROUND_UP_8(width)/2)
+#define GST_VIDEO_I420_V_ROWSTRIDE(width) ((GST_ROUND_UP_8(GST_VIDEO_I420_Y_ROWSTRIDE(width)))/2)
-static void
-gst_videoflip_base_init (gpointer g_class)
+#define GST_VIDEO_I420_Y_OFFSET(w,h) (0)
+#define GST_VIDEO_I420_U_OFFSET(w,h) (GST_VIDEO_I420_Y_OFFSET(w,h)+(GST_VIDEO_I420_Y_ROWSTRIDE(w)*GST_ROUND_UP_2(h)))
+#define GST_VIDEO_I420_V_OFFSET(w,h) (GST_VIDEO_I420_U_OFFSET(w,h)+(GST_VIDEO_I420_U_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
+
+#define GST_VIDEO_I420_SIZE(w,h) (GST_VIDEO_I420_V_OFFSET(w,h)+(GST_VIDEO_I420_V_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
+
+static gboolean
+gst_videoflip_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
+ guint * size)
{
- static GstElementDetails videoflip_details =
- GST_ELEMENT_DETAILS ("Video Flipper",
- "Filter/Effect/Video",
- "Flips and rotates video",
- "David Schleef <ds@schleef.org>");
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
- GstVideofilterClass *videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
- int i;
+ GstVideoflip *videoflip;
+ GstStructure *structure;
+ gboolean ret = FALSE;
+ gint width, height;
- gst_element_class_set_details (element_class, &videoflip_details);
+ videoflip = GST_VIDEOFLIP (btrans);
+
+ structure = gst_caps_get_structure (caps, 0);
- for (i = 0; i < G_N_ELEMENTS (gst_videoflip_formats); i++) {
- gst_videofilter_class_add_format (videofilter_class,
- gst_videoflip_formats + i);
+ if (gst_structure_get_int (structure, "width", &width) &&
+ gst_structure_get_int (structure, "height", &height)) {
+ *size = GST_VIDEO_I420_SIZE (width, height);
+ ret = TRUE;
+ GST_DEBUG_OBJECT (videoflip, "our frame size is %d bytes (%dx%d)", *size,
+ width, height);
}
- gst_videofilter_class_add_pad_templates (GST_VIDEOFILTER_CLASS (g_class));
+ return ret;
}
-static void
-gst_videoflip_class_init (gpointer g_class, gpointer class_data)
+static GstFlowReturn
+gst_videoflip_flip (GstVideoflip * videoflip, unsigned char *dest,
+ unsigned char *src, int sw, int sh, int dw, int dh)
{
- GObjectClass *gobject_class;
- GstVideofilterClass *videofilter_class;
+ GstFlowReturn ret = GST_FLOW_OK;
+ int x, y;
+
+ switch (videoflip->method) {
+ case GST_VIDEOFLIP_METHOD_90R:
+ for (y = 0; y < dh; y++) {
+ for (x = 0; x < dw; x++) {
+ dest[y * dw + x] = src[(sh - 1 - x) * sw + y];
+ }
+ }
+ break;
+ case GST_VIDEOFLIP_METHOD_90L:
+ for (y = 0; y < dh; y++) {
+ for (x = 0; x < dw; x++) {
+ dest[y * dw + x] = src[x * sw + (sw - 1 - y)];
+ }
+ }
+ break;
+ case GST_VIDEOFLIP_METHOD_180:
+ for (y = 0; y < dh; y++) {
+ for (x = 0; x < dw; x++) {
+ dest[y * dw + x] = src[(sh - 1 - y) * sw + (sw - 1 - x)];
+ }
+ }
+ break;
+ case GST_VIDEOFLIP_METHOD_HORIZ:
+ for (y = 0; y < dh; y++) {
+ for (x = 0; x < dw; x++) {
+ dest[y * dw + x] = src[y * sw + (sw - 1 - x)];
+ }
+ }
+ break;
+ case GST_VIDEOFLIP_METHOD_VERT:
+ for (y = 0; y < dh; y++) {
+ for (x = 0; x < dw; x++) {
+ dest[y * dw + x] = src[(sh - 1 - y) * sw + x];
+ }
+ }
+ break;
+ case GST_VIDEOFLIP_METHOD_TRANS:
+ for (y = 0; y < dh; y++) {
+ for (x = 0; x < dw; x++) {
+ dest[y * dw + x] = src[x * sw + y];
+ }
+ }
+ break;
+ case GST_VIDEOFLIP_METHOD_OTHER:
+ for (y = 0; y < dh; y++) {
+ for (x = 0; x < dw; x++) {
+ dest[y * dw + x] = src[(sh - 1 - x) * sw + (sw - 1 - y)];
+ }
+ }
+ break;
+ default:
+ ret = GST_FLOW_ERROR;
+ break;
+ }
- gobject_class = G_OBJECT_CLASS (g_class);
- videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
+ return ret;
+}
- gobject_class->set_property = gst_videoflip_set_property;
- gobject_class->get_property = gst_videoflip_get_property;
+static GstFlowReturn
+gst_videoflip_transform (GstBaseTransform * trans, GstBuffer * in,
+ GstBuffer * out)
+{
+ GstVideoflip *videoflip;
+ gpointer dest, src;
+ int sw, sh, dw, dh;
+ GstFlowReturn ret = GST_FLOW_OK;
- g_object_class_install_property (gobject_class, ARG_METHOD,
- g_param_spec_enum ("method", "method", "method",
- GST_TYPE_VIDEOFLIP_METHOD, GST_VIDEOFLIP_METHOD_90R,
- G_PARAM_READWRITE));
+ videoflip = GST_VIDEOFLIP (trans);
+
+ gst_buffer_stamp (out, in);
+
+ src = GST_BUFFER_DATA (in);
+ dest = GST_BUFFER_DATA (out);
+ sw = videoflip->from_width;
+ sh = videoflip->from_height;
+ dw = videoflip->to_width;
+ dh = videoflip->to_height;
+
+ GST_LOG_OBJECT (videoflip, "videoflip: scaling planar 4:1:1 %dx%d to %dx%d",
+ sw, sh, dw, dh);
+
+ ret = gst_videoflip_flip (videoflip, dest, src, sw, sh, dw, dh);
+ if (ret != GST_FLOW_OK)
+ goto beach;
+
+ src += sw * sh;
+ dest += dw * dh;
+
+ dh = dh >> 1;
+ dw = dw >> 1;
+ sh = sh >> 1;
+ sw = sw >> 1;
- videofilter_class->setup = gst_videoflip_setup;
+ ret = gst_videoflip_flip (videoflip, dest, src, sw, sh, dw, dh);
+ if (ret != GST_FLOW_OK)
+ goto beach;
+
+ src += sw * sh;
+ dest += dw * dh;
+
+ ret = gst_videoflip_flip (videoflip, dest, src, sw, sh, dw, dh);
+
+beach:
+ return ret;
}
-static void
-gst_videoflip_init (GTypeInstance * instance, gpointer g_class)
+static gboolean
+gst_videoflip_handle_src_event (GstPad * pad, GstEvent * event)
{
- GstVideoflip *videoflip = GST_VIDEOFLIP (instance);
- GstVideofilter *videofilter;
+ GstVideoflip *vf;
+ gboolean ret;
+ gdouble x, y;
+ GstStructure *structure;
+
+ vf = GST_VIDEOFLIP (gst_pad_get_parent (pad));
+
+ GST_DEBUG_OBJECT (vf, "handling %s event", GST_EVENT_TYPE_NAME (event));
+
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_NAVIGATION:
+ event =
+ GST_EVENT (gst_mini_object_make_writable (GST_MINI_OBJECT (event)));
+
+ structure = (GstStructure *) gst_event_get_structure (event);
+ if (gst_structure_get_double (structure, "pointer_x", &x) &&
+ gst_structure_get_double (structure, "pointer_y", &y)) {
+ switch (vf->method) {
+ case GST_VIDEOFLIP_METHOD_90R:
+ case GST_VIDEOFLIP_METHOD_OTHER:
+ x = y;
+ y = vf->to_width - x;
+ break;
+ case GST_VIDEOFLIP_METHOD_90L:
+ case GST_VIDEOFLIP_METHOD_TRANS:
+ x = vf->to_height - y;
+ y = x;
+ break;
+ case GST_VIDEOFLIP_METHOD_180:
+ x = vf->to_width - x;
+ y = vf->to_height - y;
+ break;
+ case GST_VIDEOFLIP_METHOD_HORIZ:
+ x = vf->to_width - x;
+ y = y;
+ break;
+ case GST_VIDEOFLIP_METHOD_VERT:
+ x = x;
+ y = vf->to_height - y;
+ break;
+ default:
+ x = x;
+ y = y;
+ break;
+ }
+ gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x,
+ "pointer_y", G_TYPE_DOUBLE, y, NULL);
+ }
+ break;
+ default:
+ break;
+ }
- GST_DEBUG_OBJECT (videoflip, "gst_videoflip_init");
+ ret = gst_pad_event_default (pad, event);
- videofilter = GST_VIDEOFILTER (videoflip);
+ gst_object_unref (vf);
- /* do stuff */
+ return ret;
}
static void
@@ -186,16 +417,25 @@ gst_videoflip_set_property (GObject * object, guint prop_id,
videoflip = GST_VIDEOFLIP (object);
videofilter = GST_VIDEOFILTER (object);
- GST_DEBUG_OBJECT (videoflip, "gst_videoflip_set_property");
switch (prop_id) {
case ARG_METHOD:
- videoflip->method = g_value_get_enum (value);
- if (videofilter->inited) {
- GST_DEBUG_OBJECT (videoflip, "setting up videoflip again");
- gst_videofilter_setup (videofilter);
+ {
+ GstVideoflipMethod method;
+
+ method = g_value_get_enum (value);
+ if (method != videoflip->method) {
+ GstBaseTransform *btrans = GST_BASE_TRANSFORM (videoflip);
+
+ g_mutex_lock (btrans->transform_lock);
+ gst_pad_set_caps (btrans->sinkpad, NULL);
+ gst_pad_set_caps (btrans->srcpad, NULL);
+ g_mutex_unlock (btrans->transform_lock);
+ videoflip->method = method;
}
+ }
break;
default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
@@ -219,167 +459,94 @@ gst_videoflip_get_property (GObject * object, guint prop_id, GValue * value,
}
}
-static gboolean
-plugin_init (GstPlugin * plugin)
+static void
+gst_videoflip_base_init (gpointer g_class)
{
- GST_DEBUG_CATEGORY_INIT (gst_videoflip_debug, "videoflip", 0, "videoflip");
-
- return gst_element_register (plugin, "videoflip", GST_RANK_NONE,
- GST_TYPE_VIDEOFLIP);
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "videoflip",
- "Flips and rotates video",
- plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-static void gst_videoflip_flip (GstVideoflip * videoflip,
- unsigned char *dest, unsigned char *src, int sw, int sh, int dw, int dh);
+ gst_element_class_set_details (element_class, &videoflip_details);
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_videoflip_sink_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_videoflip_src_template));
+}
static void
-gst_videoflip_setup (GstVideofilter * videofilter)
+gst_videoflip_class_init (gpointer klass, gpointer class_data)
{
- int from_width, from_height;
- GstVideoflip *videoflip;
-
- videoflip = GST_VIDEOFLIP (videofilter);
- GST_DEBUG_OBJECT (videoflip, "gst_videoflip_setup");
+ GObjectClass *gobject_class;
+ GstBaseTransformClass *trans_class;
- from_width = gst_videofilter_get_input_width (videofilter);
- from_height = gst_videofilter_get_input_height (videofilter);
+ gobject_class = (GObjectClass *) klass;
+ trans_class = (GstBaseTransformClass *) klass;
- if (from_width == 0 || from_height == 0) {
- return;
- }
+ parent_class = g_type_class_peek_parent (klass);
- switch (videoflip->method) {
- case GST_VIDEOFLIP_METHOD_90R:
- case GST_VIDEOFLIP_METHOD_90L:
- case GST_VIDEOFLIP_METHOD_TRANS:
- case GST_VIDEOFLIP_METHOD_OTHER:
- gst_videofilter_set_output_size (videofilter, from_height, from_width);
- break;
- case GST_VIDEOFLIP_METHOD_IDENTITY:
- case GST_VIDEOFLIP_METHOD_180:
- case GST_VIDEOFLIP_METHOD_HORIZ:
- case GST_VIDEOFLIP_METHOD_VERT:
- gst_videofilter_set_output_size (videofilter, from_width, from_height);
- break;
- default:
- g_assert_not_reached ();
- break;
- }
+ gobject_class->set_property = gst_videoflip_set_property;
+ gobject_class->get_property = gst_videoflip_get_property;
- GST_DEBUG_OBJECT (videoflip, "format=%p \"%s\" from %dx%d to %dx%d",
- videofilter->format, videofilter->format->fourcc,
- from_width, from_height, videofilter->to_width, videofilter->to_height);
+ g_object_class_install_property (gobject_class, ARG_METHOD,
+ g_param_spec_enum ("method", "method", "method",
+ GST_TYPE_VIDEOFLIP_METHOD, GST_VIDEOFLIP_METHOD_90R,
+ G_PARAM_READWRITE));
- if (videoflip->method == GST_VIDEOFLIP_METHOD_IDENTITY) {
- GST_DEBUG_OBJECT (videoflip, "videoflip: using passthru");
- videofilter->passthru = TRUE;
- } else {
- videofilter->passthru = FALSE;
- }
+ trans_class->transform_caps =
+ GST_DEBUG_FUNCPTR (gst_videoflip_transform_caps);
+ trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_videoflip_set_caps);
+ trans_class->get_unit_size = GST_DEBUG_FUNCPTR (gst_videoflip_get_unit_size);
+ trans_class->transform = GST_DEBUG_FUNCPTR (gst_videoflip_transform);
}
static void
-gst_videoflip_planar411 (GstVideofilter * videofilter, void *dest, void *src)
+gst_videoflip_init (GTypeInstance * instance, gpointer g_class)
{
- GstVideoflip *videoflip;
- int sw;
- int sh;
- int dw;
- int dh;
-
- g_return_if_fail (GST_IS_VIDEOFLIP (videofilter));
- videoflip = GST_VIDEOFLIP (videofilter);
-
- sw = videofilter->from_width;
- sh = videofilter->from_height;
- dw = videofilter->to_width;
- dh = videofilter->to_height;
-
- GST_LOG_OBJECT (videoflip, "videoflip: scaling planar 4:1:1 %dx%d to %dx%d",
- sw, sh, dw, dh);
-
- gst_videoflip_flip (videoflip, dest, src, sw, sh, dw, dh);
+ GstVideoflip *videoflip = GST_VIDEOFLIP (instance);
+ GstBaseTransform *btrans = GST_BASE_TRANSFORM (instance);
- src += sw * sh;
- dest += dw * dh;
+ GST_DEBUG_OBJECT (videoflip, "gst_videoflip_init");
- dh = dh >> 1;
- dw = dw >> 1;
- sh = sh >> 1;
- sw = sw >> 1;
+ videoflip->method = GST_VIDEOFLIP_METHOD_90R;
- gst_videoflip_flip (videoflip, dest, src, sw, sh, dw, dh);
+ gst_pad_set_event_function (btrans->srcpad,
+ GST_DEBUG_FUNCPTR (gst_videoflip_handle_src_event));
+}
- src += sw * sh;
- dest += dw * dh;
+static gboolean
+plugin_init (GstPlugin * plugin)
+{
+ GST_DEBUG_CATEGORY_INIT (videoflip_debug, "videoflip", 0, "videoflip");
- gst_videoflip_flip (videoflip, dest, src, sw, sh, dw, dh);
+ return gst_element_register (plugin, "videoflip", GST_RANK_NONE,
+ GST_TYPE_VIDEOFLIP);
}
-static void
-gst_videoflip_flip (GstVideoflip * videoflip, unsigned char *dest,
- unsigned char *src, int sw, int sh, int dw, int dh)
+GType
+gst_videoflip_get_type (void)
{
- int x, y;
+ static GType videoflip_type = 0;
- switch (videoflip->method) {
- case GST_VIDEOFLIP_METHOD_90R:
- for (y = 0; y < dh; y++) {
- for (x = 0; x < dw; x++) {
- dest[y * dw + x] = src[(sh - 1 - x) * sw + y];
- }
- }
- break;
- case GST_VIDEOFLIP_METHOD_90L:
- for (y = 0; y < dh; y++) {
- for (x = 0; x < dw; x++) {
- dest[y * dw + x] = src[x * sw + (sw - 1 - y)];
- }
- }
- break;
- case GST_VIDEOFLIP_METHOD_180:
- for (y = 0; y < dh; y++) {
- for (x = 0; x < dw; x++) {
- dest[y * dw + x] = src[(sh - 1 - y) * sw + (sw - 1 - x)];
- }
- }
- break;
- case GST_VIDEOFLIP_METHOD_HORIZ:
- for (y = 0; y < dh; y++) {
- for (x = 0; x < dw; x++) {
- dest[y * dw + x] = src[y * sw + (sw - 1 - x)];
- }
- }
- break;
- case GST_VIDEOFLIP_METHOD_VERT:
- for (y = 0; y < dh; y++) {
- for (x = 0; x < dw; x++) {
- dest[y * dw + x] = src[(sh - 1 - y) * sw + x];
- }
- }
- break;
- case GST_VIDEOFLIP_METHOD_TRANS:
- for (y = 0; y < dh; y++) {
- for (x = 0; x < dw; x++) {
- dest[y * dw + x] = src[x * sw + y];
- }
- }
- break;
- case GST_VIDEOFLIP_METHOD_OTHER:
- for (y = 0; y < dh; y++) {
- for (x = 0; x < dw; x++) {
- dest[y * dw + x] = src[(sh - 1 - x) * sw + (sw - 1 - y)];
- }
- }
- break;
- default:
- /* FIXME */
- break;
+ if (!videoflip_type) {
+ static const GTypeInfo videoflip_info = {
+ sizeof (GstVideoflipClass),
+ gst_videoflip_base_init,
+ NULL,
+ gst_videoflip_class_init,
+ NULL,
+ NULL,
+ sizeof (GstVideoflip),
+ 0,
+ gst_videoflip_init,
+ };
+
+ videoflip_type = g_type_register_static (GST_TYPE_VIDEOFILTER,
+ "GstVideoflip", &videoflip_info, 0);
}
+ return videoflip_type;
}
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ "videoflip",
+ "Flips and rotates video",
+ plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);
diff --git a/gst/videofilter/gstvideoflip.h b/gst/videofilter/gstvideoflip.h
index 83b37718..d21ed4ac 100644
--- a/gst/videofilter/gstvideoflip.h
+++ b/gst/videofilter/gstvideoflip.h
@@ -17,16 +17,11 @@
* Boston, MA 02111-1307, USA.
*/
-
#ifndef __GST_VIDEOFLIP_H__
#define __GST_VIDEOFLIP_H__
-
-#include <gst/gst.h>
-
#include "gstvideofilter.h"
-
G_BEGIN_DECLS
typedef enum {
@@ -37,7 +32,7 @@ typedef enum {
GST_VIDEOFLIP_METHOD_HORIZ,
GST_VIDEOFLIP_METHOD_VERT,
GST_VIDEOFLIP_METHOD_TRANS,
- GST_VIDEOFLIP_METHOD_OTHER,
+ GST_VIDEOFLIP_METHOD_OTHER
} GstVideoflipMethod;
#define GST_TYPE_VIDEOFLIP \
@@ -56,7 +51,10 @@ typedef struct _GstVideoflipClass GstVideoflipClass;
struct _GstVideoflip {
GstVideofilter videofilter;
-
+
+ gint from_width, from_height;
+ gint to_width, to_height;
+
GstVideoflipMethod method;
};
@@ -69,4 +67,3 @@ GType gst_videoflip_get_type(void);
G_END_DECLS
#endif /* __GST_VIDEOFLIP_H__ */
-