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
This commit is contained in:
Julien Moutte 2005-11-23 15:50:51 +00:00
parent aa454b5383
commit 65893762cd
2 changed files with 9 additions and 534 deletions

View file

@ -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)));
}

View file

@ -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;
GstBaseTransform element;
GstPad *sinkpad,*srcpad;
/* 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__ */