mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 09:10:36 +00:00
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:
parent
aa454b5383
commit
65893762cd
2 changed files with 9 additions and 534 deletions
|
@ -22,40 +22,15 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
/*#define DEBUG_ENABLED */
|
|
||||||
#include "gstvideofilter.h"
|
#include "gstvideofilter.h"
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (gst_videofilter_debug);
|
GST_DEBUG_CATEGORY_STATIC (gst_videofilter_debug);
|
||||||
#define GST_CAT_DEFAULT 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_class_init (gpointer g_class, gpointer class_data);
|
||||||
static void gst_videofilter_init (GTypeInstance * instance, gpointer g_class);
|
static void gst_videofilter_init (GTypeInstance * instance, gpointer g_class);
|
||||||
|
|
||||||
static void gst_videofilter_set_property (GObject * object, guint prop_id,
|
static GstBaseTransformClass *parent_class = NULL;
|
||||||
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;
|
|
||||||
|
|
||||||
GType
|
GType
|
||||||
gst_videofilter_get_type (void)
|
gst_videofilter_get_type (void)
|
||||||
|
@ -65,7 +40,7 @@ gst_videofilter_get_type (void)
|
||||||
if (!videofilter_type) {
|
if (!videofilter_type) {
|
||||||
static const GTypeInfo videofilter_info = {
|
static const GTypeInfo videofilter_info = {
|
||||||
sizeof (GstVideofilterClass),
|
sizeof (GstVideofilterClass),
|
||||||
gst_videofilter_base_init,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
gst_videofilter_class_init,
|
gst_videofilter_class_init,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -75,484 +50,37 @@ gst_videofilter_get_type (void)
|
||||||
gst_videofilter_init,
|
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);
|
"GstVideofilter", &videofilter_info, G_TYPE_FLAG_ABSTRACT);
|
||||||
}
|
}
|
||||||
return videofilter_type;
|
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
|
static void
|
||||||
gst_videofilter_class_init (gpointer g_class, gpointer class_data)
|
gst_videofilter_class_init (gpointer g_class, gpointer class_data)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class;
|
GObjectClass *gobject_class;
|
||||||
GstElementClass *gstelement_class;
|
GstElementClass *gstelement_class;
|
||||||
|
GstBaseTransformClass *trans_class;
|
||||||
GstVideofilterClass *klass;
|
GstVideofilterClass *klass;
|
||||||
|
|
||||||
klass = (GstVideofilterClass *) g_class;
|
klass = (GstVideofilterClass *) g_class;
|
||||||
gobject_class = (GObjectClass *) klass;
|
gobject_class = (GObjectClass *) klass;
|
||||||
gstelement_class = (GstElementClass *) klass;
|
gstelement_class = (GstElementClass *) klass;
|
||||||
|
trans_class = (GstBaseTransformClass *) klass;
|
||||||
|
|
||||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
parent_class = g_type_class_peek_parent (klass);
|
||||||
|
|
||||||
gobject_class->set_property = gst_videofilter_set_property;
|
|
||||||
gobject_class->get_property = gst_videofilter_get_property;
|
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (gst_videofilter_debug, "videofilter", 0,
|
GST_DEBUG_CATEGORY_INIT (gst_videofilter_debug, "videofilter", 0,
|
||||||
"videofilter");
|
"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
|
static void
|
||||||
gst_videofilter_init (GTypeInstance * instance, gpointer g_class)
|
gst_videofilter_init (GTypeInstance * instance, gpointer g_class)
|
||||||
{
|
{
|
||||||
GstVideofilter *videofilter = GST_VIDEOFILTER (instance);
|
GstVideofilter *videofilter = GST_VIDEOFILTER (instance);
|
||||||
GstPadTemplate *pad_template;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (videofilter, "gst_videofilter_init");
|
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;
|
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)));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,32 +21,13 @@
|
||||||
#ifndef __GST_VIDEOFILTER_H__
|
#ifndef __GST_VIDEOFILTER_H__
|
||||||
#define __GST_VIDEOFILTER_H__
|
#define __GST_VIDEOFILTER_H__
|
||||||
|
|
||||||
|
#include <gst/base/gstbasetransform.h>
|
||||||
#include <gst/gst.h>
|
|
||||||
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct _GstVideofilter GstVideofilter;
|
typedef struct _GstVideofilter GstVideofilter;
|
||||||
typedef struct _GstVideofilterClass GstVideofilterClass;
|
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 \
|
#define GST_TYPE_VIDEOFILTER \
|
||||||
(gst_videofilter_get_type())
|
(gst_videofilter_get_type())
|
||||||
#define GST_VIDEOFILTER(obj) \
|
#define GST_VIDEOFILTER(obj) \
|
||||||
|
@ -59,51 +40,17 @@ struct _GstVideofilterFormat {
|
||||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VIDEOFILTER))
|
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VIDEOFILTER))
|
||||||
|
|
||||||
struct _GstVideofilter {
|
struct _GstVideofilter {
|
||||||
GstElement element;
|
GstBaseTransform element;
|
||||||
|
|
||||||
GstPad *sinkpad,*srcpad;
|
|
||||||
|
|
||||||
/* video state */
|
|
||||||
gboolean inited;
|
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 {
|
struct _GstVideofilterClass {
|
||||||
GstElementClass parent_class;
|
GstBaseTransformClass parent_class;
|
||||||
|
|
||||||
GPtrArray *formats;
|
|
||||||
GstVideofilterSetupFunc setup;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_videofilter_get_type(void);
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_VIDEOFILTER_H__ */
|
#endif /* __GST_VIDEOFILTER_H__ */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue