opencv: port to 0.11

Basic port to 0.11 API.

https://bugzilla.gnome.org/show_bug.cgi?id=679164
This commit is contained in:
Sreerenj Balachandran 2012-06-30 00:22:40 +03:00 committed by Tim-Philipp Müller
parent 8712729a8c
commit 45ca8876b2
18 changed files with 679 additions and 619 deletions

View file

@ -323,7 +323,7 @@ GST_PLUGINS_NONPORTED=" aiff \
decklink fbdev linsys vcd \ decklink fbdev linsys vcd \
apexsink cdaudio cog dc1394 dirac directfb resindvd \ apexsink cdaudio cog dc1394 dirac directfb resindvd \
gsettings jasper ladspa mimic \ gsettings jasper ladspa mimic \
musepack musicbrainz nas neon ofa openal opencv rsvg sdl sndfile spandsp spc timidity \ musepack musicbrainz nas neon ofa openal rsvg sdl sndfile spandsp spc timidity \
directsound directdraw direct3d9 acm wininet \ directsound directdraw direct3d9 acm wininet \
wildmidi xvid lv2 teletextdec dvb sndio" wildmidi xvid lv2 teletextdec dvb sndio"
AC_SUBST(GST_PLUGINS_NONPORTED) AC_SUBST(GST_PLUGINS_NONPORTED)

View file

@ -52,39 +52,29 @@
GST_DEBUG_CATEGORY_STATIC (gst_cv_dilate_debug); GST_DEBUG_CATEGORY_STATIC (gst_cv_dilate_debug);
#define GST_CAT_DEFAULT gst_cv_dilate_debug #define GST_CAT_DEFAULT gst_cv_dilate_debug
GST_BOILERPLATE (GstCvDilate, gst_cv_dilate, GstCvDilateErode, G_DEFINE_TYPE (GstCvDilate, gst_cv_dilate, GST_TYPE_CV_DILATE_ERODE);
GST_TYPE_CV_DILATE_ERODE);
static GstFlowReturn gst_cv_dilate_transform_ip (GstOpencvVideoFilter * static GstFlowReturn gst_cv_dilate_transform_ip (GstOpencvVideoFilter *
filter, GstBuffer * buf, IplImage * img); filter, GstBuffer * buf, IplImage * img);
static GstFlowReturn gst_cv_dilate_transform (GstOpencvVideoFilter * filter, static GstFlowReturn gst_cv_dilate_transform (GstOpencvVideoFilter * filter,
GstBuffer * buf, IplImage * img, GstBuffer * outbuf, IplImage * outimg); GstBuffer * buf, IplImage * img, GstBuffer * outbuf, IplImage * outimg);
/* GObject vmethod implementations */
static void
gst_cv_dilate_base_init (gpointer gclass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
gst_element_class_set_details_simple (element_class,
"cvdilate",
"Transform/Effect/Video",
"Applies cvDilate OpenCV function to the image",
"Thiago Santos<thiago.sousa.santos@collabora.co.uk>");
}
/* initialize the cvdilate's class */ /* initialize the cvdilate's class */
static void static void
gst_cv_dilate_class_init (GstCvDilateClass * klass) gst_cv_dilate_class_init (GstCvDilateClass * klass)
{ {
GstOpencvVideoFilterClass *gstopencvbasefilter_class; GstOpencvVideoFilterClass *gstopencvbasefilter_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass; gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass;
parent_class = g_type_class_peek_parent (klass);
gstopencvbasefilter_class->cv_trans_ip_func = gst_cv_dilate_transform_ip; gstopencvbasefilter_class->cv_trans_ip_func = gst_cv_dilate_transform_ip;
gstopencvbasefilter_class->cv_trans_func = gst_cv_dilate_transform; gstopencvbasefilter_class->cv_trans_func = gst_cv_dilate_transform;
gst_element_class_set_details_simple (element_class,
"cvdilate",
"Transform/Effect/Video",
"Applies cvDilate OpenCV function to the image",
"Thiago Santos<thiago.sousa.santos@collabora.co.uk>");
} }
/* initialize the new element /* initialize the new element
@ -93,7 +83,7 @@ gst_cv_dilate_class_init (GstCvDilateClass * klass)
* initialize instance structure * initialize instance structure
*/ */
static void static void
gst_cv_dilate_init (GstCvDilate * filter, GstCvDilateClass * gclass) gst_cv_dilate_init (GstCvDilate * filter)
{ {
} }

View file

@ -75,9 +75,6 @@ enum
#define DEFAULT_ITERATIONS 1 #define DEFAULT_ITERATIONS 1
static GstElementClass *parent_class = NULL;
static void gst_cv_dilate_erode_base_init (gpointer gclass);
static void gst_cv_dilate_erode_class_init (GstCvDilateErodeClass * klass); static void gst_cv_dilate_erode_class_init (GstCvDilateErodeClass * klass);
static void gst_cv_dilate_erode_init (GstCvDilateErode * filter, static void gst_cv_dilate_erode_init (GstCvDilateErode * filter,
GstCvDilateErodeClass * gclass); GstCvDilateErodeClass * gclass);
@ -96,7 +93,7 @@ gst_cv_dilate_erode_get_type (void)
GType _type; GType _type;
static const GTypeInfo opencv_dilate_erode_info = { static const GTypeInfo opencv_dilate_erode_info = {
sizeof (GstCvDilateErodeClass), sizeof (GstCvDilateErodeClass),
(GBaseInitFunc) gst_cv_dilate_erode_base_init, NULL,
NULL, NULL,
(GClassInitFunc) gst_cv_dilate_erode_class_init, (GClassInitFunc) gst_cv_dilate_erode_class_init,
NULL, NULL,
@ -117,15 +114,25 @@ gst_cv_dilate_erode_get_type (void)
return opencv_dilate_erode_type; return opencv_dilate_erode_type;
} }
/* GObject vmethod implementations */ /* initialize the cvdilate_erode's class */
static void static void
gst_cv_dilate_erode_base_init (gpointer gclass) gst_cv_dilate_erode_class_init (GstCvDilateErodeClass * klass)
{ {
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); GObjectClass *gobject_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstCaps *caps; GstCaps *caps;
GstPadTemplate *templ; GstPadTemplate *templ;
gobject_class = (GObjectClass *) klass;
gobject_class->set_property = gst_cv_dilate_erode_set_property;
gobject_class->get_property = gst_cv_dilate_erode_get_property;
g_object_class_install_property (gobject_class, PROP_ITERATIONS,
g_param_spec_int ("iterations", "iterations",
"Number of iterations to run the algorithm", 1, G_MAXINT,
DEFAULT_ITERATIONS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/* add sink and source pad templates */ /* add sink and source pad templates */
caps = gst_opencv_caps_from_cv_image_type (CV_16UC1); caps = gst_opencv_caps_from_cv_image_type (CV_16UC1);
gst_caps_append (caps, gst_opencv_caps_from_cv_image_type (CV_8UC4)); gst_caps_append (caps, gst_opencv_caps_from_cv_image_type (CV_8UC4));
@ -134,29 +141,8 @@ gst_cv_dilate_erode_base_init (gpointer gclass)
templ = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, templ = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
gst_caps_ref (caps)); gst_caps_ref (caps));
gst_element_class_add_pad_template (element_class, templ); gst_element_class_add_pad_template (element_class, templ);
gst_object_unref (templ);
templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps); templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps);
gst_element_class_add_pad_template (element_class, templ); gst_element_class_add_pad_template (element_class, templ);
gst_object_unref (templ);
}
/* initialize the cvdilate_erode's class */
static void
gst_cv_dilate_erode_class_init (GstCvDilateErodeClass * klass)
{
GObjectClass *gobject_class;
gobject_class = (GObjectClass *) klass;
parent_class = g_type_class_peek_parent (klass);
gobject_class->set_property = gst_cv_dilate_erode_set_property;
gobject_class->get_property = gst_cv_dilate_erode_get_property;
g_object_class_install_property (gobject_class, PROP_ITERATIONS,
g_param_spec_int ("iterations", "iterations",
"Number of iterations to run the algorithm", 1, G_MAXINT,
DEFAULT_ITERATIONS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
} }
/* initialize the new element /* initialize the new element

View file

@ -56,26 +56,29 @@ GST_DEBUG_CATEGORY_STATIC (gst_cv_equalize_hist_debug);
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_GRAY8)); GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("GRAY8")));
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_GRAY8)); GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("GRAY8")));
GST_BOILERPLATE (GstCvEqualizeHist, gst_cv_equalize_hist, G_DEFINE_TYPE (GstCvEqualizeHist, gst_cv_equalize_hist,
GstOpencvVideoFilter, GST_TYPE_OPENCV_VIDEO_FILTER); GST_TYPE_OPENCV_VIDEO_FILTER);
static GstFlowReturn gst_cv_equalize_hist_transform (GstOpencvVideoFilter * static GstFlowReturn gst_cv_equalize_hist_transform (GstOpencvVideoFilter *
filter, GstBuffer * buf, IplImage * img, GstBuffer * outbuf, filter, GstBuffer * buf, IplImage * img, GstBuffer * outbuf,
IplImage * outimg); IplImage * outimg);
/* GObject vmethod implementations */
static void static void
gst_cv_equalize_hist_base_init (gpointer gclass) gst_cv_equalize_hist_class_init (GstCvEqualizeHistClass * klass)
{ {
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); GstOpencvVideoFilterClass *gstopencvbasefilter_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass;
gstopencvbasefilter_class->cv_trans_func = gst_cv_equalize_hist_transform;
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory)); gst_static_pad_template_get (&src_factory));
@ -90,19 +93,7 @@ gst_cv_equalize_hist_base_init (gpointer gclass)
} }
static void static void
gst_cv_equalize_hist_class_init (GstCvEqualizeHistClass * klass) gst_cv_equalize_hist_init (GstCvEqualizeHist * filter)
{
GstOpencvVideoFilterClass *gstopencvbasefilter_class;
gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass;
parent_class = g_type_class_peek_parent (klass);
gstopencvbasefilter_class->cv_trans_func = gst_cv_equalize_hist_transform;
}
static void
gst_cv_equalize_hist_init (GstCvEqualizeHist * filter,
GstCvEqualizeHistClass * gclass)
{ {
gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), FALSE); gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), FALSE);
} }

View file

@ -52,39 +52,29 @@
GST_DEBUG_CATEGORY_STATIC (gst_cv_erode_debug); GST_DEBUG_CATEGORY_STATIC (gst_cv_erode_debug);
#define GST_CAT_DEFAULT gst_cv_erode_debug #define GST_CAT_DEFAULT gst_cv_erode_debug
GST_BOILERPLATE (GstCvErode, gst_cv_erode, GstCvDilateErode, G_DEFINE_TYPE (GstCvErode, gst_cv_erode, GST_TYPE_CV_DILATE_ERODE);
GST_TYPE_CV_DILATE_ERODE);
static GstFlowReturn gst_cv_erode_transform_ip (GstOpencvVideoFilter * static GstFlowReturn gst_cv_erode_transform_ip (GstOpencvVideoFilter *
filter, GstBuffer * buf, IplImage * img); filter, GstBuffer * buf, IplImage * img);
static GstFlowReturn gst_cv_erode_transform (GstOpencvVideoFilter * filter, static GstFlowReturn gst_cv_erode_transform (GstOpencvVideoFilter * filter,
GstBuffer * buf, IplImage * img, GstBuffer * outbuf, IplImage * outimg); GstBuffer * buf, IplImage * img, GstBuffer * outbuf, IplImage * outimg);
/* GObject vmethod implementations */
static void
gst_cv_erode_base_init (gpointer gclass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
gst_element_class_set_details_simple (element_class,
"cverode",
"Transform/Effect/Video",
"Applies cvErode OpenCV function to the image",
"Thiago Santos<thiago.sousa.santos@collabora.co.uk>");
}
/* initialize the cverode's class */ /* initialize the cverode's class */
static void static void
gst_cv_erode_class_init (GstCvErodeClass * klass) gst_cv_erode_class_init (GstCvErodeClass * klass)
{ {
GstOpencvVideoFilterClass *gstopencvbasefilter_class; GstOpencvVideoFilterClass *gstopencvbasefilter_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass; gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass;
parent_class = g_type_class_peek_parent (klass);
gstopencvbasefilter_class->cv_trans_ip_func = gst_cv_erode_transform_ip; gstopencvbasefilter_class->cv_trans_ip_func = gst_cv_erode_transform_ip;
gstopencvbasefilter_class->cv_trans_func = gst_cv_erode_transform; gstopencvbasefilter_class->cv_trans_func = gst_cv_erode_transform;
gst_element_class_set_details_simple (element_class,
"cverode",
"Transform/Effect/Video",
"Applies cvErode OpenCV function to the image",
"Thiago Santos<thiago.sousa.santos@collabora.co.uk>");
} }
/* initialize the new element /* initialize the new element
@ -93,7 +83,7 @@ gst_cv_erode_class_init (GstCvErodeClass * klass)
* initialize instance structure * initialize instance structure
*/ */
static void static void
gst_cv_erode_init (GstCvErode * filter, GstCvErodeClass * gclass) gst_cv_erode_init (GstCvErode * filter)
{ {
} }

View file

@ -56,20 +56,22 @@ GST_DEBUG_CATEGORY_STATIC (gst_cv_laplace_debug);
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_GRAY8) GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("GRAY8"))
); );
#if G_BYTE_ORDER == G_BIG_ENDIAN #if G_BYTE_ORDER == G_BIG_ENDIAN
#define BYTE_ORDER_STRING "BIG_ENDIAN"
#else
#define BYTE_ORDER_STRING "LITTLE_ENDIAN"
#endif
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_GRAY16 (BYTE_ORDER_STRING)) GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("GRAY16_BE"))
); );
#else
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("GRAY16_LE"))
);
#endif
/* Filter signals and args */ /* Filter signals and args */
enum enum
@ -85,8 +87,7 @@ enum
#define DEFAULT_APERTURE_SIZE 3 #define DEFAULT_APERTURE_SIZE 3
GST_BOILERPLATE (GstCvLaplace, gst_cv_laplace, GstOpencvVideoFilter, G_DEFINE_TYPE (GstCvLaplace, gst_cv_laplace, GST_TYPE_OPENCV_VIDEO_FILTER);
GST_TYPE_OPENCV_VIDEO_FILTER);
static void gst_cv_laplace_set_property (GObject * object, guint prop_id, static void gst_cv_laplace_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
@ -94,7 +95,7 @@ static void gst_cv_laplace_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static GstCaps *gst_cv_laplace_transform_caps (GstBaseTransform * trans, static GstCaps *gst_cv_laplace_transform_caps (GstBaseTransform * trans,
GstPadDirection dir, GstCaps * caps); GstPadDirection dir, GstCaps * caps, GstCaps * filter);
static GstFlowReturn gst_cv_laplace_transform (GstOpencvVideoFilter * filter, static GstFlowReturn gst_cv_laplace_transform (GstOpencvVideoFilter * filter,
GstBuffer * buf, IplImage * img, GstBuffer * outbuf, IplImage * outimg); GstBuffer * buf, IplImage * img, GstBuffer * outbuf, IplImage * outimg);
@ -112,26 +113,7 @@ gst_cv_laplace_finalize (GObject * obj)
if (filter->intermediary_img) if (filter->intermediary_img)
cvReleaseImage (&filter->intermediary_img); cvReleaseImage (&filter->intermediary_img);
G_OBJECT_CLASS (parent_class)->finalize (obj); G_OBJECT_CLASS (gst_cv_laplace_parent_class)->finalize (obj);
}
/* GObject vmethod implementations */
static void
gst_cv_laplace_base_init (gpointer gclass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
gst_element_class_set_details_simple (element_class,
"cvlaplace",
"Transform/Effect/Video",
"Applies cvLaplace OpenCV function to the image",
"Thiago Santos<thiago.sousa.santos@collabora.co.uk>");
} }
/* initialize the cvlaplace's class */ /* initialize the cvlaplace's class */
@ -141,13 +123,12 @@ gst_cv_laplace_class_init (GstCvLaplaceClass * klass)
GObjectClass *gobject_class; GObjectClass *gobject_class;
GstBaseTransformClass *gstbasetransform_class; GstBaseTransformClass *gstbasetransform_class;
GstOpencvVideoFilterClass *gstopencvbasefilter_class; GstOpencvVideoFilterClass *gstopencvbasefilter_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
gstbasetransform_class = (GstBaseTransformClass *) klass; gstbasetransform_class = (GstBaseTransformClass *) klass;
gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass; gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass;
parent_class = g_type_class_peek_parent (klass);
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_cv_laplace_finalize); gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_cv_laplace_finalize);
gobject_class->set_property = gst_cv_laplace_set_property; gobject_class->set_property = gst_cv_laplace_set_property;
gobject_class->get_property = gst_cv_laplace_get_property; gobject_class->get_property = gst_cv_laplace_get_property;
@ -161,10 +142,21 @@ gst_cv_laplace_class_init (GstCvLaplaceClass * klass)
g_param_spec_int ("aperture-size", "aperture size", g_param_spec_int ("aperture-size", "aperture size",
"Size of the extended Laplace Kernel (1, 3, 5 or 7)", 1, 7, "Size of the extended Laplace Kernel (1, 3, 5 or 7)", 1, 7,
DEFAULT_APERTURE_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); DEFAULT_APERTURE_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
gst_element_class_set_details_simple (element_class,
"cvlaplace",
"Transform/Effect/Video",
"Applies cvLaplace OpenCV function to the image",
"Thiago Santos<thiago.sousa.santos@collabora.co.uk>");
} }
static void static void
gst_cv_laplace_init (GstCvLaplace * filter, GstCvLaplaceClass * gclass) gst_cv_laplace_init (GstCvLaplace * filter)
{ {
filter->aperture_size = DEFAULT_APERTURE_SIZE; filter->aperture_size = DEFAULT_APERTURE_SIZE;
@ -189,7 +181,6 @@ gst_cv_laplace_cv_set_caps (GstOpencvVideoFilter * trans, gint in_width,
GST_WARNING_OBJECT (filter, "Unsupported output depth %d", out_depth); GST_WARNING_OBJECT (filter, "Unsupported output depth %d", out_depth);
return FALSE; return FALSE;
} }
if (filter->intermediary_img) { if (filter->intermediary_img) {
cvReleaseImage (&filter->intermediary_img); cvReleaseImage (&filter->intermediary_img);
} }
@ -202,41 +193,71 @@ gst_cv_laplace_cv_set_caps (GstOpencvVideoFilter * trans, gint in_width,
static GstCaps * static GstCaps *
gst_cv_laplace_transform_caps (GstBaseTransform * trans, GstPadDirection dir, gst_cv_laplace_transform_caps (GstBaseTransform * trans, GstPadDirection dir,
GstCaps * caps) GstCaps * caps, GstCaps * filter)
{ {
GstCaps *output = NULL; GstCaps *to, *ret;
GstCaps *templ;
GstStructure *structure; GstStructure *structure;
GstPad *other;
gint i; gint i;
output = gst_caps_copy (caps); to = gst_caps_new_empty ();
for (i = 0; i < gst_caps_get_size (caps); i++) {
const GValue *v;
GValue list = { 0, };
GValue val = { 0, };
structure = gst_structure_copy (gst_caps_get_structure (caps, i));
g_value_init (&list, GST_TYPE_LIST);
g_value_init (&val, G_TYPE_STRING);
g_value_set_string (&val, "GRAY8");
gst_value_list_append_value (&list, &val);
g_value_unset (&val);
g_value_init (&val, G_TYPE_STRING);
#if G_BYTE_ORDER == G_BIG_ENDIAN
g_value_set_string (&val, "GRAY16_BE");
#else
g_value_set_string (&val, "GRAY16_LE");
#endif
gst_value_list_append_value (&list, &val);
g_value_unset (&val);
v = gst_structure_get_value (structure, "format");
gst_value_list_merge (&val, v, &list);
gst_structure_set_value (structure, "format", &val);
g_value_unset (&val);
g_value_unset (&list);
gst_structure_remove_field (structure, "colorimetry");
gst_structure_remove_field (structure, "chroma-site");
gst_caps_append_structure (to, structure);
/* we accept anything from the template caps for either side */
switch (dir) {
case GST_PAD_SINK:
for (i = 0; i < gst_caps_get_size (output); i++) {
structure = gst_caps_get_structure (output, i);
gst_structure_set (structure,
"depth", G_TYPE_INT, 16,
"bpp", G_TYPE_INT, 16,
"endianness", G_TYPE_INT, G_BYTE_ORDER, NULL);
}
break;
case GST_PAD_SRC:
for (i = 0; i < gst_caps_get_size (output); i++) {
structure = gst_caps_get_structure (output, i);
gst_structure_set (structure,
"depth", G_TYPE_INT, 8, "bpp", G_TYPE_INT, 8, NULL);
gst_structure_remove_field (structure, "endianness");
}
break;
default:
gst_caps_unref (output);
output = NULL;
g_assert_not_reached ();
break;
} }
return output; /* filter against set allowed caps on the pad */
other = (dir == GST_PAD_SINK) ? trans->srcpad : trans->sinkpad;
templ = gst_pad_get_pad_template_caps (other);
ret = gst_caps_intersect (to, templ);
gst_caps_unref (to);
gst_caps_unref (templ);
if (ret && filter) {
GstCaps *intersection;
intersection =
gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
gst_caps_unref (ret);
ret = intersection;
}
return ret;
} }
static void static void

View file

@ -106,8 +106,7 @@ gst_cv_smooth_type_get_type (void)
#define DEFAULT_PARAM3 0.0 #define DEFAULT_PARAM3 0.0
#define DEFAULT_PARAM4 0.0 #define DEFAULT_PARAM4 0.0
GST_BOILERPLATE (GstCvSmooth, gst_cv_smooth, GstOpencvVideoFilter, G_DEFINE_TYPE (GstCvSmooth, gst_cv_smooth, GST_TYPE_OPENCV_VIDEO_FILTER);
GST_TYPE_OPENCV_VIDEO_FILTER);
static void gst_cv_smooth_set_property (GObject * object, guint prop_id, static void gst_cv_smooth_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
@ -119,45 +118,19 @@ static GstFlowReturn gst_cv_smooth_transform_ip (GstOpencvVideoFilter *
static GstFlowReturn gst_cv_smooth_transform (GstOpencvVideoFilter * filter, static GstFlowReturn gst_cv_smooth_transform (GstOpencvVideoFilter * filter,
GstBuffer * buf, IplImage * img, GstBuffer * outbuf, IplImage * outimg); GstBuffer * buf, IplImage * img, GstBuffer * outbuf, IplImage * outimg);
/* GObject vmethod implementations */
static void
gst_cv_smooth_base_init (gpointer gclass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
GstCaps *caps;
GstPadTemplate *templ;
gst_element_class_set_details_simple (element_class,
"cvsmooth",
"Transform/Effect/Video",
"Applies cvSmooth OpenCV function to the image",
"Thiago Santos<thiago.sousa.santos@collabora.co.uk>");
/* add sink and source pad templates */
caps = gst_opencv_caps_from_cv_image_type (CV_8UC3);
gst_caps_append (caps, gst_opencv_caps_from_cv_image_type (CV_8UC1));
templ = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
gst_caps_ref (caps));
gst_element_class_add_pad_template (element_class, templ);
gst_object_unref (templ);
templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps);
gst_element_class_add_pad_template (element_class, templ);
gst_object_unref (templ);
}
/* initialize the cvsmooth's class */ /* initialize the cvsmooth's class */
static void static void
gst_cv_smooth_class_init (GstCvSmoothClass * klass) gst_cv_smooth_class_init (GstCvSmoothClass * klass)
{ {
GObjectClass *gobject_class; GObjectClass *gobject_class;
GstOpencvVideoFilterClass *gstopencvbasefilter_class; GstOpencvVideoFilterClass *gstopencvbasefilter_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstCaps *caps;
GstPadTemplate *templ;
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass; gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass;
parent_class = g_type_class_peek_parent (klass);
gobject_class->set_property = gst_cv_smooth_set_property; gobject_class->set_property = gst_cv_smooth_set_property;
gobject_class->get_property = gst_cv_smooth_get_property; gobject_class->get_property = gst_cv_smooth_get_property;
@ -201,6 +174,21 @@ gst_cv_smooth_class_init (GstCvSmoothClass * klass)
"/documentation/image_filtering.html#cvSmooth", "/documentation/image_filtering.html#cvSmooth",
0, G_MAXDOUBLE, DEFAULT_PARAM4, 0, G_MAXDOUBLE, DEFAULT_PARAM4,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_set_details_simple (element_class,
"cvsmooth",
"Transform/Effect/Video",
"Applies cvSmooth OpenCV function to the image",
"Thiago Santos<thiago.sousa.santos@collabora.co.uk>");
/* add sink and source pad templates */
caps = gst_opencv_caps_from_cv_image_type (CV_8UC3);
gst_caps_append (caps, gst_opencv_caps_from_cv_image_type (CV_8UC1));
templ = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
gst_caps_ref (caps));
gst_element_class_add_pad_template (element_class, templ);
templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps);
gst_element_class_add_pad_template (element_class, templ);
} }
/* initialize the new element /* initialize the new element
@ -209,7 +197,7 @@ gst_cv_smooth_class_init (GstCvSmoothClass * klass)
* initialize instance structure * initialize instance structure
*/ */
static void static void
gst_cv_smooth_init (GstCvSmooth * filter, GstCvSmoothClass * gclass) gst_cv_smooth_init (GstCvSmooth * filter)
{ {
filter->type = DEFAULT_CV_SMOOTH_TYPE; filter->type = DEFAULT_CV_SMOOTH_TYPE;
filter->param1 = DEFAULT_PARAM1; filter->param1 = DEFAULT_PARAM1;

View file

@ -56,20 +56,23 @@ GST_DEBUG_CATEGORY_STATIC (gst_cv_sobel_debug);
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_GRAY8) GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("GRAY8"))
); );
#if G_BYTE_ORDER == G_BIG_ENDIAN
#define BYTE_ORDER_STRING "BIG_ENDIAN"
#else
#define BYTE_ORDER_STRING "LITTLE_ENDIAN"
#endif
#if G_BYTE_ORDER == G_BIG_ENDIAN
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_GRAY16 (BYTE_ORDER_STRING)) GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("GRAY16_BE"))
); );
#else
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("GRAY16_LE"))
);
#endif
/* Filter signals and args */ /* Filter signals and args */
enum enum
@ -89,8 +92,7 @@ enum
#define DEFAULT_Y_ORDER 0 #define DEFAULT_Y_ORDER 0
#define DEFAULT_APERTURE_SIZE 3 #define DEFAULT_APERTURE_SIZE 3
GST_BOILERPLATE (GstCvSobel, gst_cv_sobel, GstOpencvVideoFilter, G_DEFINE_TYPE (GstCvSobel, gst_cv_sobel, GST_TYPE_OPENCV_VIDEO_FILTER);
GST_TYPE_OPENCV_VIDEO_FILTER);
static void gst_cv_sobel_set_property (GObject * object, guint prop_id, static void gst_cv_sobel_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
@ -98,30 +100,11 @@ static void gst_cv_sobel_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static GstCaps *gst_cv_sobel_transform_caps (GstBaseTransform * trans, static GstCaps *gst_cv_sobel_transform_caps (GstBaseTransform * trans,
GstPadDirection dir, GstCaps * caps); GstPadDirection dir, GstCaps * caps, GstCaps * filter);
static GstFlowReturn gst_cv_sobel_transform (GstOpencvVideoFilter * filter, static GstFlowReturn gst_cv_sobel_transform (GstOpencvVideoFilter * filter,
GstBuffer * buf, IplImage * img, GstBuffer * outbuf, IplImage * outimg); GstBuffer * buf, IplImage * img, GstBuffer * outbuf, IplImage * outimg);
/* GObject vmethod implementations */
static void
gst_cv_sobel_base_init (gpointer gclass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
gst_element_class_set_details_simple (element_class,
"cvsobel",
"Transform/Effect/Video",
"Applies cvSobel OpenCV function to the image",
"Thiago Santos<thiago.sousa.santos@collabora.co.uk>");
}
/* initialize the cvsobel's class */ /* initialize the cvsobel's class */
static void static void
gst_cv_sobel_class_init (GstCvSobelClass * klass) gst_cv_sobel_class_init (GstCvSobelClass * klass)
@ -130,12 +113,11 @@ gst_cv_sobel_class_init (GstCvSobelClass * klass)
GstBaseTransformClass *gstbasetransform_class; GstBaseTransformClass *gstbasetransform_class;
GstOpencvVideoFilterClass *gstopencvbasefilter_class; GstOpencvVideoFilterClass *gstopencvbasefilter_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
gstbasetransform_class = (GstBaseTransformClass *) klass; gstbasetransform_class = (GstBaseTransformClass *) klass;
gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass; gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass;
parent_class = g_type_class_peek_parent (klass);
gobject_class->set_property = gst_cv_sobel_set_property; gobject_class->set_property = gst_cv_sobel_set_property;
gobject_class->get_property = gst_cv_sobel_get_property; gobject_class->get_property = gst_cv_sobel_get_property;
@ -155,10 +137,21 @@ gst_cv_sobel_class_init (GstCvSobelClass * klass)
g_param_spec_int ("aperture-size", "aperture size", g_param_spec_int ("aperture-size", "aperture size",
"Size of the extended Sobel Kernel (1, 3, 5 or 7)", 1, 7, "Size of the extended Sobel Kernel (1, 3, 5 or 7)", 1, 7,
DEFAULT_APERTURE_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); DEFAULT_APERTURE_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
gst_element_class_set_details_simple (element_class,
"cvsobel",
"Transform/Effect/Video",
"Applies cvSobel OpenCV function to the image",
"Thiago Santos<thiago.sousa.santos@collabora.co.uk>");
} }
static void static void
gst_cv_sobel_init (GstCvSobel * filter, GstCvSobelClass * gclass) gst_cv_sobel_init (GstCvSobel * filter)
{ {
filter->x_order = DEFAULT_X_ORDER; filter->x_order = DEFAULT_X_ORDER;
filter->y_order = DEFAULT_Y_ORDER; filter->y_order = DEFAULT_Y_ORDER;
@ -169,41 +162,69 @@ gst_cv_sobel_init (GstCvSobel * filter, GstCvSobelClass * gclass)
static GstCaps * static GstCaps *
gst_cv_sobel_transform_caps (GstBaseTransform * trans, GstPadDirection dir, gst_cv_sobel_transform_caps (GstBaseTransform * trans, GstPadDirection dir,
GstCaps * caps) GstCaps * caps, GstCaps * filter)
{ {
GstCaps *output = NULL; GstCaps *to, *ret;
GstCaps *templ;
GstStructure *structure; GstStructure *structure;
GstPad *other;
gint i; gint i;
output = gst_caps_copy (caps); to = gst_caps_new_empty ();
for (i = 0; i < gst_caps_get_size (caps); i++) {
const GValue *v;
GValue list = { 0, };
GValue val = { 0, };
structure = gst_structure_copy (gst_caps_get_structure (caps, i));
g_value_init (&list, GST_TYPE_LIST);
g_value_init (&val, G_TYPE_STRING);
g_value_set_string (&val, "GRAY8");
gst_value_list_append_value (&list, &val);
g_value_unset (&val);
g_value_init (&val, G_TYPE_STRING);
#if G_BYTE_ORDER == G_BIG_ENDIAN
g_value_set_string (&val, "GRAY16_BE");
#else
g_value_set_string (&val, "GRAY16_LE");
#endif
gst_value_list_append_value (&list, &val);
g_value_unset (&val);
v = gst_structure_get_value (structure, "format");
gst_value_list_merge (&val, v, &list);
gst_structure_set_value (structure, "format", &val);
g_value_unset (&val);
g_value_unset (&list);
gst_structure_remove_field (structure, "colorimetry");
gst_structure_remove_field (structure, "chroma-site");
gst_caps_append_structure (to, structure);
/* we accept anything from the template caps for either side */
switch (dir) {
case GST_PAD_SINK:
for (i = 0; i < gst_caps_get_size (output); i++) {
structure = gst_caps_get_structure (output, i);
gst_structure_set (structure,
"depth", G_TYPE_INT, 16,
"bpp", G_TYPE_INT, 16,
"endianness", G_TYPE_INT, G_BYTE_ORDER, NULL);
} }
break; /* filter against set allowed caps on the pad */
case GST_PAD_SRC: other = (dir == GST_PAD_SINK) ? trans->srcpad : trans->sinkpad;
for (i = 0; i < gst_caps_get_size (output); i++) { templ = gst_pad_get_pad_template_caps (other);
structure = gst_caps_get_structure (output, i); ret = gst_caps_intersect (to, templ);
gst_structure_set (structure, gst_caps_unref (to);
"depth", G_TYPE_INT, 8, "bpp", G_TYPE_INT, 8, NULL); gst_caps_unref (templ);
gst_structure_remove_field (structure, "endianness");
} if (ret && filter) {
break; GstCaps *intersection;
default:
gst_caps_unref (output); intersection =
output = NULL; gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
g_assert_not_reached (); gst_caps_unref (ret);
break; ret = intersection;
} }
return output; return ret;
} }
static void static void

View file

@ -91,24 +91,26 @@ enum
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB"))
); );
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB"))
); );
GST_BOILERPLATE (GstEdgeDetect, gst_edge_detect, GstElement, GST_TYPE_ELEMENT); G_DEFINE_TYPE (GstEdgeDetect, gst_edge_detect, GST_TYPE_ELEMENT);
static void gst_edge_detect_set_property (GObject * object, guint prop_id, static void gst_edge_detect_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
static void gst_edge_detect_get_property (GObject * object, guint prop_id, static void gst_edge_detect_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static gboolean gst_edge_detect_set_caps (GstPad * pad, GstCaps * caps); static gboolean gst_edge_detect_handle_sink_event (GstPad * pad,
static GstFlowReturn gst_edge_detect_chain (GstPad * pad, GstBuffer * buf); GstObject * parent, GstEvent * event);
static GstFlowReturn gst_edge_detect_chain (GstPad * pad, GstObject * parent,
GstBuffer * buf);
/* Clean up */ /* Clean up */
static void static void
@ -123,25 +125,7 @@ gst_edge_detect_finalize (GObject * obj)
cvReleaseImage (&filter->cvEdge); cvReleaseImage (&filter->cvEdge);
} }
G_OBJECT_CLASS (parent_class)->finalize (obj); G_OBJECT_CLASS (gst_edge_detect_parent_class)->finalize (obj);
}
/* GObject vmethod implementations */
static void
gst_edge_detect_base_init (gpointer gclass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
gst_element_class_set_details_simple (element_class,
"edgedetect",
"Filter/Effect/Video",
"Performs canny edge detection on videos and images.",
"Michael Sheldon <mike@mikeasoft.com>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
} }
/* initialize the edgedetect's class */ /* initialize the edgedetect's class */
@ -150,6 +134,7 @@ gst_edge_detect_class_init (GstEdgeDetectClass * klass)
{ {
GObjectClass *gobject_class; GObjectClass *gobject_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_edge_detect_finalize); gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_edge_detect_finalize);
@ -172,6 +157,17 @@ gst_edge_detect_class_init (GstEdgeDetectClass * klass)
g_param_spec_int ("aperture", "Aperture", g_param_spec_int ("aperture", "Aperture",
"Aperture size for Sobel operator (Must be either 3, 5 or 7", 3, 7, 3, "Aperture size for Sobel operator (Must be either 3, 5 or 7", 3, 7, 3,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_set_details_simple (element_class,
"edgedetect",
"Filter/Effect/Video",
"Performs canny edge detection on videos and images.",
"Michael Sheldon <mike@mikeasoft.com>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
} }
/* initialize the new element /* initialize the new element
@ -180,19 +176,17 @@ gst_edge_detect_class_init (GstEdgeDetectClass * klass)
* initialize instance structure * initialize instance structure
*/ */
static void static void
gst_edge_detect_init (GstEdgeDetect * filter, GstEdgeDetectClass * gclass) gst_edge_detect_init (GstEdgeDetect * filter)
{ {
filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink"); filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
gst_pad_set_setcaps_function (filter->sinkpad, GST_PAD_SET_PROXY_CAPS (filter->sinkpad);
GST_DEBUG_FUNCPTR (gst_edge_detect_set_caps)); gst_pad_set_event_function (filter->sinkpad,
gst_pad_set_getcaps_function (filter->sinkpad, GST_DEBUG_FUNCPTR (gst_edge_detect_handle_sink_event));
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
gst_pad_set_chain_function (filter->sinkpad, gst_pad_set_chain_function (filter->sinkpad,
GST_DEBUG_FUNCPTR (gst_edge_detect_chain)); GST_DEBUG_FUNCPTR (gst_edge_detect_chain));
filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src"); filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
gst_pad_set_getcaps_function (filter->srcpad, GST_PAD_SET_PROXY_CAPS (filter->srcpad);
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
@ -256,14 +250,22 @@ gst_edge_detect_get_property (GObject * object, guint prop_id,
/* this function handles the link with other elements */ /* this function handles the link with other elements */
static gboolean static gboolean
gst_edge_detect_set_caps (GstPad * pad, GstCaps * caps) gst_edge_detect_handle_sink_event (GstPad * pad, GstObject * parent,
GstEvent * event)
{ {
GstEdgeDetect *filter; GstEdgeDetect *filter;
GstPad *otherpad;
gint width, height; gint width, height;
GstStructure *structure; GstStructure *structure;
gboolean res = TRUE;
filter = GST_EDGE_DETECT (parent);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_CAPS:
{
GstCaps *caps;
gst_event_parse_caps (event, &caps);
filter = GST_EDGE_DETECT (gst_pad_get_parent (pad));
structure = gst_caps_get_structure (caps, 0); structure = gst_caps_get_structure (caps, 0);
gst_structure_get_int (structure, "width", &width); gst_structure_get_int (structure, "width", &width);
gst_structure_get_int (structure, "height", &height); gst_structure_get_int (structure, "height", &height);
@ -272,25 +274,34 @@ gst_edge_detect_set_caps (GstPad * pad, GstCaps * caps)
filter->cvCEdge = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 3); filter->cvCEdge = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 3);
filter->cvGray = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 1); filter->cvGray = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 1);
filter->cvEdge = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 1); filter->cvEdge = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 1);
break;
}
default:
break;
}
otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad; res = gst_pad_event_default (pad, parent, event);
gst_object_unref (filter);
return res;
return gst_pad_set_caps (otherpad, caps);
} }
/* chain function /* chain function
* this function does the actual processing * this function does the actual processing
*/ */
static GstFlowReturn static GstFlowReturn
gst_edge_detect_chain (GstPad * pad, GstBuffer * buf) gst_edge_detect_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{ {
GstEdgeDetect *filter; GstEdgeDetect *filter;
GstBuffer *outbuf; GstBuffer *outbuf;
GstMapInfo in_info;
GstMapInfo out_info;
filter = GST_EDGE_DETECT (GST_OBJECT_PARENT (pad)); filter = GST_EDGE_DETECT (parent);
filter->cvImage->imageData = (char *) GST_BUFFER_DATA (buf); buf = gst_buffer_make_writable (buf);
gst_buffer_map (buf, &in_info, GST_MAP_WRITE);
filter->cvImage->imageData = (char *) in_info.data;
cvCvtColor (filter->cvImage, filter->cvGray, CV_RGB2GRAY); cvCvtColor (filter->cvImage, filter->cvGray, CV_RGB2GRAY);
cvSmooth (filter->cvGray, filter->cvEdge, CV_BLUR, 3, 3, 0, 0); cvSmooth (filter->cvGray, filter->cvEdge, CV_BLUR, 3, 3, 0, 0);
@ -306,10 +317,14 @@ gst_edge_detect_chain (GstPad * pad, GstBuffer * buf)
} }
outbuf = gst_buffer_new_and_alloc (filter->cvCEdge->imageSize); outbuf = gst_buffer_new_and_alloc (filter->cvCEdge->imageSize);
gst_buffer_copy_metadata (outbuf, buf, GST_BUFFER_COPY_ALL); gst_buffer_copy_into (outbuf, buf, GST_BUFFER_COPY_METADATA, 0, -1);
memcpy (GST_BUFFER_DATA (outbuf), filter->cvCEdge->imageData,
GST_BUFFER_SIZE (outbuf));
gst_buffer_map (outbuf, &out_info, GST_MAP_WRITE);
memcpy (out_info.data, filter->cvCEdge->imageData,
gst_buffer_get_size (outbuf));
gst_buffer_unmap (buf, &in_info);
gst_buffer_unmap (outbuf, &out_info);
gst_buffer_unref (buf); gst_buffer_unref (buf);
return gst_pad_push (filter->srcpad, outbuf); return gst_pad_push (filter->srcpad, outbuf);
} }

View file

@ -89,24 +89,26 @@ enum
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB"))
); );
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB"))
); );
GST_BOILERPLATE (GstFaceBlur, gst_face_blur, GstElement, GST_TYPE_ELEMENT); G_DEFINE_TYPE (GstFaceBlur, gst_face_blur, GST_TYPE_ELEMENT);
static void gst_face_blur_set_property (GObject * object, guint prop_id, static void gst_face_blur_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
static void gst_face_blur_get_property (GObject * object, guint prop_id, static void gst_face_blur_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static gboolean gst_face_blur_set_caps (GstPad * pad, GstCaps * caps); static gboolean gst_face_blur_handle_sink_event (GstPad * pad,
static GstFlowReturn gst_face_blur_chain (GstPad * pad, GstBuffer * buf); GstObject * parent, GstEvent * event);
static GstFlowReturn gst_face_blur_chain (GstPad * pad, GstObject * parent,
GstBuffer * buf);
static void gst_face_blur_load_profile (GstFaceBlur * filter); static void gst_face_blur_load_profile (GstFaceBlur * filter);
@ -123,15 +125,27 @@ gst_face_blur_finalize (GObject * obj)
g_free (filter->profile); g_free (filter->profile);
G_OBJECT_CLASS (parent_class)->finalize (obj); G_OBJECT_CLASS (gst_face_blur_parent_class)->finalize (obj);
} }
/* GObject vmethod implementations */ /* initialize the faceblur's class */
static void static void
gst_face_blur_base_init (gpointer gclass) gst_face_blur_class_init (GstFaceBlurClass * klass)
{ {
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); GObjectClass *gobject_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gobject_class = (GObjectClass *) klass;
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_face_blur_finalize);
gobject_class->set_property = gst_face_blur_set_property;
gobject_class->get_property = gst_face_blur_get_property;
g_object_class_install_property (gobject_class, PROP_PROFILE,
g_param_spec_string ("profile", "Profile",
"Location of Haar cascade file to use for face blurion",
DEFAULT_PROFILE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_set_details_simple (element_class, gst_element_class_set_details_simple (element_class,
"faceblur", "faceblur",
@ -145,44 +159,23 @@ gst_face_blur_base_init (gpointer gclass)
gst_static_pad_template_get (&sink_factory)); gst_static_pad_template_get (&sink_factory));
} }
/* initialize the faceblur's class */
static void
gst_face_blur_class_init (GstFaceBlurClass * klass)
{
GObjectClass *gobject_class;
gobject_class = (GObjectClass *) klass;
parent_class = g_type_class_peek_parent (klass);
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_face_blur_finalize);
gobject_class->set_property = gst_face_blur_set_property;
gobject_class->get_property = gst_face_blur_get_property;
g_object_class_install_property (gobject_class, PROP_PROFILE,
g_param_spec_string ("profile", "Profile",
"Location of Haar cascade file to use for face blurion",
DEFAULT_PROFILE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}
/* initialize the new element /* initialize the new element
* instantiate pads and add them to element * instantiate pads and add them to element
* set pad calback functions * set pad calback functions
* initialize instance structure * initialize instance structure
*/ */
static void static void
gst_face_blur_init (GstFaceBlur * filter, GstFaceBlurClass * gclass) gst_face_blur_init (GstFaceBlur * filter)
{ {
filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink"); filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
gst_pad_set_setcaps_function (filter->sinkpad, GST_PAD_SET_PROXY_CAPS (filter->sinkpad);
GST_DEBUG_FUNCPTR (gst_face_blur_set_caps)); gst_pad_set_event_function (filter->sinkpad,
gst_pad_set_getcaps_function (filter->sinkpad, GST_DEBUG_FUNCPTR (gst_face_blur_handle_sink_event));
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
gst_pad_set_chain_function (filter->sinkpad, gst_pad_set_chain_function (filter->sinkpad,
GST_DEBUG_FUNCPTR (gst_face_blur_chain)); GST_DEBUG_FUNCPTR (gst_face_blur_chain));
filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src"); filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
gst_pad_set_getcaps_function (filter->srcpad, GST_PAD_SET_PROXY_CAPS (filter->srcpad);
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
@ -228,14 +221,22 @@ gst_face_blur_get_property (GObject * object, guint prop_id,
/* this function handles the link with other elements */ /* this function handles the link with other elements */
static gboolean static gboolean
gst_face_blur_set_caps (GstPad * pad, GstCaps * caps) gst_face_blur_handle_sink_event (GstPad * pad, GstObject * parent,
GstEvent * event)
{ {
GstFaceBlur *filter; GstFaceBlur *filter;
GstPad *otherpad;
gint width, height; gint width, height;
GstStructure *structure; GstStructure *structure;
gboolean res = TRUE;
filter = GST_FACE_BLUR (parent);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_CAPS:
{
GstCaps *caps;
gst_event_parse_caps (event, &caps);
filter = GST_FACE_BLUR (gst_pad_get_parent (pad));
structure = gst_caps_get_structure (caps, 0); structure = gst_caps_get_structure (caps, 0);
gst_structure_get_int (structure, "width", &width); gst_structure_get_int (structure, "width", &width);
gst_structure_get_int (structure, "height", &height); gst_structure_get_int (structure, "height", &height);
@ -243,26 +244,33 @@ gst_face_blur_set_caps (GstPad * pad, GstCaps * caps)
filter->cvImage = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 3); filter->cvImage = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 3);
filter->cvGray = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 1); filter->cvGray = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 1);
filter->cvStorage = cvCreateMemStorage (0); filter->cvStorage = cvCreateMemStorage (0);
break;
}
default:
break;
}
otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad; res = gst_pad_event_default (pad, parent, event);
gst_object_unref (filter);
return gst_pad_set_caps (otherpad, caps); return res;
} }
/* chain function /* chain function
* this function does the actual processing * this function does the actual processing
*/ */
static GstFlowReturn static GstFlowReturn
gst_face_blur_chain (GstPad * pad, GstBuffer * buf) gst_face_blur_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{ {
GstFaceBlur *filter; GstFaceBlur *filter;
CvSeq *faces; CvSeq *faces;
GstMapInfo info;
int i; int i;
filter = GST_FACE_BLUR (GST_OBJECT_PARENT (pad)); filter = GST_FACE_BLUR (GST_OBJECT_PARENT (pad));
filter->cvImage->imageData = (char *) GST_BUFFER_DATA (buf); buf = gst_buffer_make_writable (buf);
gst_buffer_map (buf, &info, GST_MAP_READWRITE);
filter->cvImage->imageData = (char *) info.data;
cvCvtColor (filter->cvImage, filter->cvGray, CV_RGB2GRAY); cvCvtColor (filter->cvImage, filter->cvGray, CV_RGB2GRAY);
cvClearMemStorage (filter->cvStorage); cvClearMemStorage (filter->cvStorage);

View file

@ -154,17 +154,16 @@ gst_opencv_face_detect_flags_get_type (void)
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB"))
); );
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB"))
); );
GST_BOILERPLATE (GstFaceDetect, gst_face_detect, GstOpencvVideoFilter, G_DEFINE_TYPE (GstFaceDetect, gst_face_detect, GST_TYPE_OPENCV_VIDEO_FILTER);
GST_TYPE_OPENCV_VIDEO_FILTER);
static void gst_face_detect_set_property (GObject * object, guint prop_id, static void gst_face_detect_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
@ -205,26 +204,7 @@ gst_face_detect_finalize (GObject * obj)
if (filter->cvEyesDetect) if (filter->cvEyesDetect)
cvReleaseHaarClassifierCascade (&filter->cvEyesDetect); cvReleaseHaarClassifierCascade (&filter->cvEyesDetect);
G_OBJECT_CLASS (parent_class)->finalize (obj); G_OBJECT_CLASS (gst_face_detect_parent_class)->finalize (obj);
}
/* GObject vmethod implementations */
static void
gst_face_detect_base_init (gpointer gclass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
gst_element_class_set_details_simple (element_class,
"facedetect",
"Filter/Effect/Video",
"Performs face detection on videos and images, providing detected positions via bus messages",
"Michael Sheldon <mike@mikeasoft.com>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
} }
/* initialize the facedetect's class */ /* initialize the facedetect's class */
@ -234,6 +214,7 @@ gst_face_detect_class_init (GstFaceDetectClass * klass)
GObjectClass *gobject_class; GObjectClass *gobject_class;
GstOpencvVideoFilterClass *gstopencvbasefilter_class; GstOpencvVideoFilterClass *gstopencvbasefilter_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass; gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass;
@ -288,13 +269,24 @@ gst_face_detect_class_init (GstFaceDetectClass * klass)
g_param_spec_int ("min-size-height", "Minimum face height", g_param_spec_int ("min-size-height", "Minimum face height",
"Minimum area height to be recognized as a face", 0, G_MAXINT, "Minimum area height to be recognized as a face", 0, G_MAXINT,
DEFAULT_MIN_SIZE_HEIGHT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); DEFAULT_MIN_SIZE_HEIGHT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_set_details_simple (element_class,
"facedetect",
"Filter/Effect/Video",
"Performs face detection on videos and images, providing detected positions via bus messages",
"Michael Sheldon <mike@mikeasoft.com>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
} }
/* initialize the new element /* initialize the new element
* initialize instance structure * initialize instance structure
*/ */
static void static void
gst_face_detect_init (GstFaceDetect * filter, GstFaceDetectClass * gclass) gst_face_detect_init (GstFaceDetect * filter)
{ {
filter->face_profile = g_strdup (DEFAULT_FACE_PROFILE); filter->face_profile = g_strdup (DEFAULT_FACE_PROFILE);
filter->nose_profile = g_strdup (DEFAULT_NOSE_PROFILE); filter->nose_profile = g_strdup (DEFAULT_NOSE_PROFILE);
@ -679,7 +671,8 @@ gst_face_detect_transform_ip (GstOpencvVideoFilter * base, GstBuffer * buf,
} }
} }
gst_structure_set_value (msg->structure, "faces", &facelist); gst_structure_set_value ((GstStructure *) gst_message_get_structure (msg),
"faces", &facelist);
g_value_unset (&facelist); g_value_unset (&facelist);
gst_element_post_message (GST_ELEMENT (filter), msg); gst_element_post_message (GST_ELEMENT (filter), msg);
} }

View file

@ -143,23 +143,24 @@ enum
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB)); GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB")));
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB)); GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB")));
GST_BOILERPLATE (GstMotioncells, gst_motion_cells, GstElement, G_DEFINE_TYPE (GstMotioncells, gst_motion_cells, GST_TYPE_ELEMENT);
GST_TYPE_ELEMENT);
static void gst_motion_cells_set_property (GObject * object, guint prop_id, static void gst_motion_cells_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
static void gst_motion_cells_get_property (GObject * object, guint prop_id, static void gst_motion_cells_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static gboolean gst_motion_cells_set_caps (GstPad * pad, GstCaps * caps); static gboolean gst_motion_cells_handle_sink_event (GstPad * pad,
static GstFlowReturn gst_motion_cells_chain (GstPad * pad, GstBuffer * buf); GstObject * parent, GstEvent * event);
static GstFlowReturn gst_motion_cells_chain (GstPad * pad, GstObject * parent,
GstBuffer * buf);
static void gst_motioncells_update_motion_cells (GstMotioncells * filter); static void gst_motioncells_update_motion_cells (GstMotioncells * filter);
static void gst_motioncells_update_motion_masks (GstMotioncells * filter); static void gst_motioncells_update_motion_masks (GstMotioncells * filter);
@ -194,25 +195,7 @@ gst_motion_cells_finalize (GObject * obj)
GFREE (filter->basename_datafile); GFREE (filter->basename_datafile);
GFREE (filter->datafile_extension); GFREE (filter->datafile_extension);
G_OBJECT_CLASS (parent_class)->finalize (obj); G_OBJECT_CLASS (gst_motion_cells_parent_class)->finalize (obj);
}
/* GObject vmethod implementations */
static void
gst_motion_cells_base_init (gpointer gclass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
gst_element_class_set_details_simple (element_class,
"motioncells",
"Filter/Effect/Video",
"Performs motion detection on videos and images, providing detected motion cells index via bus messages",
"Robert Jobbagy <jobbagy dot robert at gmail dot com>, Nicola Murino <nicola dot murino at gmail.com>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
} }
/* initialize the motioncells's class */ /* initialize the motioncells's class */
@ -221,8 +204,8 @@ gst_motion_cells_class_init (GstMotioncellsClass * klass)
{ {
GObjectClass *gobject_class; GObjectClass *gobject_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
parent_class = g_type_class_peek_parent (klass);
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_motion_cells_finalize); gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_motion_cells_finalize);
gobject_class->set_property = gst_motion_cells_set_property; gobject_class->set_property = gst_motion_cells_set_property;
@ -316,6 +299,17 @@ gst_motion_cells_class_init (GstMotioncellsClass * klass)
"Motion Cell Border Thickness, if it's -1 then motion cell will be fill", "Motion Cell Border Thickness, if it's -1 then motion cell will be fill",
THICKNESS_MIN, THICKNESS_MAX, THICKNESS_DEF, THICKNESS_MIN, THICKNESS_MAX, THICKNESS_DEF,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_set_details_simple (element_class,
"motioncells",
"Filter/Effect/Video",
"Performs motion detection on videos and images, providing detected motion cells index via bus messages",
"Robert Jobbagy <jobbagy dot robert at gmail dot com>, Nicola Murino <nicola dot murino at gmail.com>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
} }
/* initialize the new element /* initialize the new element
@ -324,19 +318,18 @@ gst_motion_cells_class_init (GstMotioncellsClass * klass)
* initialize instance structure * initialize instance structure
*/ */
static void static void
gst_motion_cells_init (GstMotioncells * filter, GstMotioncellsClass * gclass) gst_motion_cells_init (GstMotioncells * filter)
{ {
filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink"); filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
gst_pad_set_setcaps_function (filter->sinkpad, GST_PAD_SET_PROXY_CAPS (filter->sinkpad);
GST_DEBUG_FUNCPTR (gst_motion_cells_set_caps));
gst_pad_set_getcaps_function (filter->sinkpad, gst_pad_set_event_function (filter->sinkpad,
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); GST_DEBUG_FUNCPTR (gst_motion_cells_handle_sink_event));
gst_pad_set_chain_function (filter->sinkpad, gst_pad_set_chain_function (filter->sinkpad,
GST_DEBUG_FUNCPTR (gst_motion_cells_chain)); GST_DEBUG_FUNCPTR (gst_motion_cells_chain));
filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src"); filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
gst_pad_set_getcaps_function (filter->srcpad, GST_PAD_SET_PROXY_CAPS (filter->srcpad);
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
@ -817,38 +810,53 @@ gst_motioncells_update_motion_masks (GstMotioncells * filter)
/* this function handles the link with other elements */ /* this function handles the link with other elements */
static gboolean static gboolean
gst_motion_cells_set_caps (GstPad * pad, GstCaps * caps) gst_motion_cells_handle_sink_event (GstPad * pad, GstObject * parent,
GstEvent * event)
{ {
GstMotioncells *filter; GstMotioncells *filter;
GstPad *otherpad; GstVideoInfo info;
GstStructure *structure; gboolean res = TRUE;
int numerator, denominator;
filter = gst_motion_cells (gst_pad_get_parent (pad)); filter = gst_motion_cells (parent);
structure = gst_caps_get_structure (caps, 0);
gst_structure_get_int (structure, "width", &filter->width); switch (GST_EVENT_TYPE (event)) {
gst_structure_get_int (structure, "height", &filter->height); case GST_EVENT_CAPS:
gst_structure_get_fraction (structure, "framerate", &numerator, &denominator); {
filter->framerate = (double) numerator / (double) denominator; GstCaps *caps;
gst_event_parse_caps (event, &caps);
gst_video_info_from_caps (&info, caps);
filter->width = info.width;
filter->height = info.height;
filter->framerate = (double) info.fps_n / (double) info.fps_d;
if (filter->cvImage) if (filter->cvImage)
cvReleaseImage (&filter->cvImage); cvReleaseImage (&filter->cvImage);
filter->cvImage = filter->cvImage =
cvCreateImage (cvSize (filter->width, filter->height), IPL_DEPTH_8U, 3); cvCreateImage (cvSize (filter->width, filter->height), IPL_DEPTH_8U,
3);
break;
}
default:
break;
}
res = gst_pad_event_default (pad, parent, event);
return res;
otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad;
gst_object_unref (filter);
return gst_pad_set_caps (otherpad, caps);
} }
/* chain function /* chain function
* this function does the actual processing * this function does the actual processing
*/ */
static GstFlowReturn static GstFlowReturn
gst_motion_cells_chain (GstPad * pad, GstBuffer * buf) gst_motion_cells_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{ {
GstMotioncells *filter; GstMotioncells *filter;
filter = gst_motion_cells (GST_OBJECT_PARENT (pad)); GstMapInfo info;
filter = gst_motion_cells (parent);
GST_OBJECT_LOCK (filter); GST_OBJECT_LOCK (filter);
if (filter->calculate_motion) { if (filter->calculate_motion) {
double sensitivity; double sensitivity;
@ -865,8 +873,10 @@ gst_motion_cells_chain (GstPad * pad, GstBuffer * buf)
motioncellidx *motionmaskcellsidx; motioncellidx *motionmaskcellsidx;
cellscolor motioncellscolor; cellscolor motioncellscolor;
motioncellidx *motioncellsidx; motioncellidx *motioncellsidx;
buf = gst_buffer_make_writable (buf); buf = gst_buffer_make_writable (buf);
filter->cvImage->imageData = (char *) GST_BUFFER_DATA (buf); gst_buffer_map (buf, &info, GST_MAP_WRITE);
filter->cvImage->imageData = (char *) info.data;
if (filter->firstframe) { if (filter->firstframe) {
setPrevFrame (filter->cvImage, filter->id); setPrevFrame (filter->cvImage, filter->id);
filter->firstframe = FALSE; filter->firstframe = FALSE;

View file

@ -29,31 +29,34 @@ static gboolean
gst_opencv_get_ipl_depth_and_channels (GstStructure * structure, gst_opencv_get_ipl_depth_and_channels (GstStructure * structure,
gint * ipldepth, gint * channels, GError ** err) gint * ipldepth, gint * channels, GError ** err)
{ {
gint depth, bpp; GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
const GstVideoFormatInfo *info;
gint depth = 0, i;
const gchar *s;
if (!gst_structure_get_int (structure, "depth", &depth) || if (gst_structure_has_name (structure, "video/x-raw")) {
!gst_structure_get_int (structure, "bpp", &bpp)) { if (!(s = gst_structure_get_string (structure, "format")))
g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION, return FALSE;
"No depth/bpp in caps"); format = gst_video_format_from_string (s);
if (format == GST_VIDEO_FORMAT_UNKNOWN)
return FALSE; return FALSE;
} }
if (depth != bpp) { info = gst_video_format_get_info (format);
g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION,
"Depth and bpp should be equal");
return FALSE;
}
if (gst_structure_has_name (structure, "video/x-raw-rgb")) { if (GST_VIDEO_FORMAT_INFO_IS_RGB (info))
*channels=3; *channels=3;
} else if (gst_structure_has_name (structure, "video/x-raw-gray")) { else if (GST_VIDEO_FORMAT_INFO_IS_GRAY (info))
*channels=1; *channels=1;
} else { else {
g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION, g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION,
"Unsupported caps %s", gst_structure_get_name (structure)); "Unsupported structure %s", gst_structure_get_name (structure));
return FALSE; return FALSE;
} }
for (i = 0; i < GST_VIDEO_FORMAT_INFO_N_COMPONENTS (info); i++)
depth += GST_VIDEO_FORMAT_INFO_DEPTH (info, i);
if (depth / *channels == 8) { if (depth / *channels == 8) {
/* TODO signdness? */ /* TODO signdness? */
*ipldepth = IPL_DEPTH_8U; *ipldepth = IPL_DEPTH_8U;
@ -92,9 +95,42 @@ gboolean
gst_opencv_parse_iplimage_params_from_caps (GstCaps * caps, gint * width, gst_opencv_parse_iplimage_params_from_caps (GstCaps * caps, gint * width,
gint * height, gint * ipldepth, gint * channels, GError ** err) gint * height, gint * ipldepth, gint * channels, GError ** err)
{ {
return GstVideoInfo info;
gst_opencv_parse_iplimage_params_from_structure (gst_caps_get_structure gint i, depth = 0;
(caps, 0), width, height, ipldepth, channels, err);
if (!gst_video_info_from_caps (&info, caps)) {
GST_ERROR ("Failed to get the videoinfo from caps");
g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION,
"No width/heighti/depth/channels in caps");
return FALSE;
}
*width = GST_VIDEO_INFO_WIDTH (&info);
*height = GST_VIDEO_INFO_HEIGHT (&info);
if (GST_VIDEO_INFO_IS_RGB (&info))
*channels = 3;
else if (GST_VIDEO_INFO_IS_GRAY (&info))
*channels = 1;
else {
g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION,
"Unsupported caps %s", gst_caps_to_string(caps));
return FALSE;
}
for (i = 0; i < GST_VIDEO_INFO_N_COMPONENTS (&info); i++)
depth += GST_VIDEO_INFO_COMP_DEPTH (&info, i);
if (depth / *channels == 8) {
/* TODO signdness? */
*ipldepth = IPL_DEPTH_8U;
} else if (depth / *channels == 16) {
*ipldepth = IPL_DEPTH_16U;
} else {
g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION,
"Unsupported depth/channels %d/%d", depth, *channels);
return FALSE;
}
return TRUE;
} }
GstCaps * GstCaps *

View file

@ -73,7 +73,6 @@ static void gst_opencv_video_filter_class_init (GstOpencvVideoFilterClass *
klass); klass);
static void gst_opencv_video_filter_init (GstOpencvVideoFilter * trans, static void gst_opencv_video_filter_init (GstOpencvVideoFilter * trans,
GstOpencvVideoFilterClass * klass); GstOpencvVideoFilterClass * klass);
static void gst_opencv_video_filter_base_init (gpointer gclass);
static gboolean gst_opencv_video_filter_set_caps (GstBaseTransform * trans, static gboolean gst_opencv_video_filter_set_caps (GstBaseTransform * trans,
GstCaps * incaps, GstCaps * outcaps); GstCaps * incaps, GstCaps * outcaps);
@ -96,7 +95,7 @@ gst_opencv_video_filter_get_type (void)
GType _type; GType _type;
static const GTypeInfo opencv_base_transform_info = { static const GTypeInfo opencv_base_transform_info = {
sizeof (GstOpencvVideoFilterClass), sizeof (GstOpencvVideoFilterClass),
(GBaseInitFunc) gst_opencv_video_filter_base_init, NULL,
NULL, NULL,
(GClassInitFunc) gst_opencv_video_filter_class_init, (GClassInitFunc) gst_opencv_video_filter_class_init,
NULL, NULL,
@ -128,12 +127,6 @@ gst_opencv_video_filter_finalize (GObject * obj)
G_OBJECT_CLASS (parent_class)->finalize (obj); G_OBJECT_CLASS (parent_class)->finalize (obj);
} }
/* GObject vmethod implementations */
static void
gst_opencv_video_filter_base_init (gpointer gclass)
{
}
static void static void
gst_opencv_video_filter_class_init (GstOpencvVideoFilterClass * klass) gst_opencv_video_filter_class_init (GstOpencvVideoFilterClass * klass)
{ {
@ -159,7 +152,7 @@ gst_opencv_video_filter_class_init (GstOpencvVideoFilterClass * klass)
static void static void
gst_opencv_video_filter_init (GstOpencvVideoFilter * transform, gst_opencv_video_filter_init (GstOpencvVideoFilter * transform,
GstOpencvVideoFilterClass * bclass) GstOpencvVideoFilterClass * klass)
{ {
} }
@ -169,6 +162,8 @@ gst_opencv_video_filter_transform (GstBaseTransform * trans,
{ {
GstOpencvVideoFilter *transform; GstOpencvVideoFilter *transform;
GstOpencvVideoFilterClass *fclass; GstOpencvVideoFilterClass *fclass;
GstMapInfo in_info;
GstMapInfo out_info;
GstFlowReturn ret; GstFlowReturn ret;
transform = GST_OPENCV_VIDEO_FILTER (trans); transform = GST_OPENCV_VIDEO_FILTER (trans);
@ -178,16 +173,17 @@ gst_opencv_video_filter_transform (GstBaseTransform * trans,
g_return_val_if_fail (transform->cvImage != NULL, GST_FLOW_ERROR); g_return_val_if_fail (transform->cvImage != NULL, GST_FLOW_ERROR);
g_return_val_if_fail (transform->out_cvImage != NULL, GST_FLOW_ERROR); g_return_val_if_fail (transform->out_cvImage != NULL, GST_FLOW_ERROR);
transform->cvImage->imageData = (char *) gst_buffer_map (inbuf, gst_buffer_map (inbuf, &in_info, GST_MAP_READ);
NULL, NULL, GST_MAP_READ); transform->cvImage->imageData = (char *) in_info.data;
transform->out_cvImage->imageData = (char *) gst_buffer_map (outbuf,
NULL, NULL, GST_MAP_WRITE); gst_buffer_map (outbuf, &out_info, GST_MAP_WRITE);
transform->out_cvImage->imageData = (char *) out_info.data;
ret = fclass->cv_trans_func (transform, inbuf, transform->cvImage, outbuf, ret = fclass->cv_trans_func (transform, inbuf, transform->cvImage, outbuf,
transform->out_cvImage); transform->out_cvImage);
gst_buffer_unmap (inbuf, transform->cvImage->imageData, -1); gst_buffer_unmap (inbuf, &in_info);
gst_buffer_unmap (outbuf, transform->out_cvImage->imageData, -1); gst_buffer_unmap (outbuf, &out_info);
return ret; return ret;
} }
@ -198,6 +194,7 @@ gst_opencv_video_filter_transform_ip (GstBaseTransform * trans,
{ {
GstOpencvVideoFilter *transform; GstOpencvVideoFilter *transform;
GstOpencvVideoFilterClass *fclass; GstOpencvVideoFilterClass *fclass;
GstMapInfo info;
GstFlowReturn ret; GstFlowReturn ret;
transform = GST_OPENCV_VIDEO_FILTER (trans); transform = GST_OPENCV_VIDEO_FILTER (trans);
@ -210,13 +207,13 @@ gst_opencv_video_filter_transform_ip (GstBaseTransform * trans,
* level */ * level */
buffer = gst_buffer_make_writable (buffer); buffer = gst_buffer_make_writable (buffer);
transform->cvImage->imageData = (char *) gst_buffer_map (buffer, gst_buffer_map (buffer, &info, GST_MAP_READWRITE);
NULL, NULL, GST_MAP_READWRITE); transform->cvImage->imageData = (char *) info.data;
/* FIXME how to release buffer? */ /* FIXME how to release buffer? */
ret = fclass->cv_trans_ip_func (transform, buffer, transform->cvImage); ret = fclass->cv_trans_ip_func (transform, buffer, transform->cvImage);
gst_buffer_unmap (buffer, transform->cvImage->imageData, -1); gst_buffer_unmap (buffer, &info);
return ret; return ret;
} }

View file

@ -93,25 +93,26 @@ enum
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB"))
); );
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB"))
); );
GST_BOILERPLATE (GstPyramidSegment, gst_pyramid_segment, GstElement, G_DEFINE_TYPE (GstPyramidSegment, gst_pyramid_segment, GST_TYPE_ELEMENT);
GST_TYPE_ELEMENT);
static void gst_pyramid_segment_set_property (GObject * object, guint prop_id, static void gst_pyramid_segment_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
static void gst_pyramid_segment_get_property (GObject * object, guint prop_id, static void gst_pyramid_segment_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static gboolean gst_pyramid_segment_set_caps (GstPad * pad, GstCaps * caps); static gboolean gst_pyramid_segment_handle_sink_event (GstPad * pad,
static GstFlowReturn gst_pyramid_segment_chain (GstPad * pad, GstBuffer * buf); GstObject * parent, GstEvent * event);
static GstFlowReturn gst_pyramid_segment_chain (GstPad * pad,
GstObject * parent, GstBuffer * buf);
/* Clean up */ /* Clean up */
static void static void
@ -124,26 +125,10 @@ gst_pyramid_segment_finalize (GObject * obj)
cvReleaseImage (&filter->cvSegmentedImage); cvReleaseImage (&filter->cvSegmentedImage);
} }
G_OBJECT_CLASS (parent_class)->finalize (obj); G_OBJECT_CLASS (gst_pyramid_segment_parent_class)->finalize (obj);
} }
/* GObject vmethod implementations */
static void
gst_pyramid_segment_base_init (gpointer gclass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
gst_element_class_set_details_simple (element_class,
"pyramidsegment",
"Filter/Effect/Video",
"Applies pyramid segmentation to a video or image.",
"Michael Sheldon <mike@mikeasoft.com>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
}
/* initialize the pyramidsegment's class */ /* initialize the pyramidsegment's class */
static void static void
@ -151,8 +136,8 @@ gst_pyramid_segment_class_init (GstPyramidSegmentClass * klass)
{ {
GObjectClass *gobject_class; GObjectClass *gobject_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
parent_class = g_type_class_peek_parent (klass);
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_pyramid_segment_finalize); gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_pyramid_segment_finalize);
gobject_class->set_property = gst_pyramid_segment_set_property; gobject_class->set_property = gst_pyramid_segment_set_property;
@ -176,6 +161,17 @@ gst_pyramid_segment_class_init (GstPyramidSegmentClass * klass)
g_param_spec_int ("level", "Level", g_param_spec_int ("level", "Level",
"Maximum level of the pyramid segmentation", 0, 4, 4, "Maximum level of the pyramid segmentation", 0, 4, 4,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_set_details_simple (element_class,
"pyramidsegment",
"Filter/Effect/Video",
"Applies pyramid segmentation to a video or image.",
"Michael Sheldon <mike@mikeasoft.com>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
} }
/* initialize the new element /* initialize the new element
@ -184,20 +180,18 @@ gst_pyramid_segment_class_init (GstPyramidSegmentClass * klass)
* initialize instance structure * initialize instance structure
*/ */
static void static void
gst_pyramid_segment_init (GstPyramidSegment * filter, gst_pyramid_segment_init (GstPyramidSegment * filter)
GstPyramidSegmentClass * gclass)
{ {
filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink"); filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
gst_pad_set_setcaps_function (filter->sinkpad, GST_PAD_SET_PROXY_CAPS (filter->sinkpad);
GST_DEBUG_FUNCPTR (gst_pyramid_segment_set_caps));
gst_pad_set_getcaps_function (filter->sinkpad, gst_pad_set_event_function (filter->sinkpad,
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); GST_DEBUG_FUNCPTR (gst_pyramid_segment_handle_sink_event));
gst_pad_set_chain_function (filter->sinkpad, gst_pad_set_chain_function (filter->sinkpad,
GST_DEBUG_FUNCPTR (gst_pyramid_segment_chain)); GST_DEBUG_FUNCPTR (gst_pyramid_segment_chain));
filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src"); filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
gst_pad_set_getcaps_function (filter->srcpad, GST_PAD_SET_PROXY_CAPS (filter->srcpad);
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
@ -264,39 +258,50 @@ gst_pyramid_segment_get_property (GObject * object, guint prop_id,
/* this function handles the link with other elements */ /* this function handles the link with other elements */
static gboolean static gboolean
gst_pyramid_segment_set_caps (GstPad * pad, GstCaps * caps) gst_pyramid_segment_handle_sink_event (GstPad * pad, GstObject * parent,
GstEvent * event)
{ {
GstPyramidSegment *filter; GstPyramidSegment *filter;
GstPad *otherpad; GstVideoInfo info;
GstStructure *structure; gboolean res = TRUE;
gint width, height; filter = GST_PYRAMID_SEGMENT (parent);
filter = GST_PYRAMID_SEGMENT (gst_pad_get_parent (pad)); switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_CAPS:
{
GstCaps *caps;
gst_event_parse_caps (event, &caps);
gst_video_info_from_caps (&info, caps);
structure = gst_caps_get_structure (caps, 0); filter->cvImage =
gst_structure_get_int (structure, "width", &width); cvCreateImage (cvSize (info.width, info.height), IPL_DEPTH_8U, 3);
gst_structure_get_int (structure, "height", &height); break;
}
default:
break;
}
filter->cvImage = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 3); res = gst_pad_event_default (pad, parent, event);
otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad; return res;
gst_object_unref (filter);
return gst_pad_set_caps (otherpad, caps);
} }
/* chain function /* chain function
* this function does the actual processing * this function does the actual processing
*/ */
static GstFlowReturn static GstFlowReturn
gst_pyramid_segment_chain (GstPad * pad, GstBuffer * buf) gst_pyramid_segment_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{ {
GstPyramidSegment *filter; GstPyramidSegment *filter;
GstBuffer *outbuf; GstBuffer *outbuf;
GstMapInfo info;
GstMapInfo outinfo;
filter = GST_PYRAMID_SEGMENT (GST_OBJECT_PARENT (pad)); filter = GST_PYRAMID_SEGMENT (GST_OBJECT_PARENT (pad));
filter->cvImage->imageData = (char *) GST_BUFFER_DATA (buf); buf = gst_buffer_make_writable (buf);
gst_buffer_map (buf, &info, GST_MAP_READWRITE);
filter->cvImage->imageData = (char *) info.data;
filter->cvSegmentedImage = cvCloneImage (filter->cvImage); filter->cvSegmentedImage = cvCloneImage (filter->cvImage);
cvPyrSegmentation (filter->cvImage, filter->cvSegmentedImage, filter->storage, cvPyrSegmentation (filter->cvImage, filter->cvSegmentedImage, filter->storage,
@ -306,14 +311,17 @@ gst_pyramid_segment_chain (GstPad * pad, GstBuffer * buf)
* delete only the struct headers. Would avoid a memcpy here */ * delete only the struct headers. Would avoid a memcpy here */
outbuf = gst_buffer_new_and_alloc (filter->cvSegmentedImage->imageSize); outbuf = gst_buffer_new_and_alloc (filter->cvSegmentedImage->imageSize);
gst_buffer_copy_metadata (outbuf, buf, GST_BUFFER_COPY_ALL); gst_buffer_copy_into (outbuf, buf, GST_BUFFER_COPY_METADATA, 0, -1);
memcpy (GST_BUFFER_DATA (outbuf), filter->cvSegmentedImage->imageData, gst_buffer_map (outbuf, &outinfo, GST_MAP_WRITE);
GST_BUFFER_SIZE (outbuf)); memcpy (outinfo.data, filter->cvSegmentedImage->imageData,
gst_buffer_get_size (outbuf));
gst_buffer_unmap (buf, &info);
gst_buffer_unref (buf); gst_buffer_unref (buf);
cvReleaseImage (&filter->cvSegmentedImage); cvReleaseImage (&filter->cvSegmentedImage);
g_assert (filter->cvSegmentedImage == NULL); g_assert (filter->cvSegmentedImage == NULL);
gst_buffer_unmap (outbuf, &outinfo);
return gst_pad_push (filter->srcpad, outbuf); return gst_pad_push (filter->srcpad, outbuf);
} }

View file

@ -91,17 +91,16 @@ enum
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB"))
); );
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB"))
); );
GST_BOILERPLATE (GstTemplateMatch, gst_template_match, GstElement, G_DEFINE_TYPE (GstTemplateMatch, gst_template_match, GST_TYPE_ELEMENT);
GST_TYPE_ELEMENT);
static void gst_template_match_finalize (GObject * object); static void gst_template_match_finalize (GObject * object);
static void gst_template_match_set_property (GObject * object, guint prop_id, static void gst_template_match_set_property (GObject * object, guint prop_id,
@ -109,37 +108,23 @@ static void gst_template_match_set_property (GObject * object, guint prop_id,
static void gst_template_match_get_property (GObject * object, guint prop_id, static void gst_template_match_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static gboolean gst_template_match_set_caps (GstPad * pad, GstCaps * caps); static gboolean gst_template_match_handle_sink_event (GstPad * pad,
static GstFlowReturn gst_template_match_chain (GstPad * pad, GstBuffer * buf); GstObject * parent, GstEvent * event);
static GstFlowReturn gst_template_match_chain (GstPad * pad, GstObject * parent,
GstBuffer * buf);
static void gst_template_match_load_template (GstTemplateMatch * filter); static void gst_template_match_load_template (GstTemplateMatch * filter);
static void gst_template_match_match (IplImage * input, IplImage * template, static void gst_template_match_match (IplImage * input, IplImage * template,
IplImage * dist_image, double *best_res, CvPoint * best_pos, int method); IplImage * dist_image, double *best_res, CvPoint * best_pos, int method);
/* GObject vmethod implementations */
static void
gst_template_match_base_init (gpointer gclass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
gst_element_class_set_details_simple (element_class,
"templatematch",
"Filter/Effect/Video",
"Performs template matching on videos and images, providing detected positions via bus messages.",
"Noam Lewis <jones.noamle@gmail.com>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
}
/* initialize the templatematch's class */ /* initialize the templatematch's class */
static void static void
gst_template_match_class_init (GstTemplateMatchClass * klass) gst_template_match_class_init (GstTemplateMatchClass * klass)
{ {
GObjectClass *gobject_class; GObjectClass *gobject_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
@ -158,6 +143,17 @@ gst_template_match_class_init (GstTemplateMatchClass * klass)
g_param_spec_boolean ("display", "Display", g_param_spec_boolean ("display", "Display",
"Sets whether the detected template should be highlighted in the output", "Sets whether the detected template should be highlighted in the output",
TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_set_details_simple (element_class,
"templatematch",
"Filter/Effect/Video",
"Performs template matching on videos and images, providing detected positions via bus messages.",
"Noam Lewis <jones.noamle@gmail.com>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
} }
/* initialize the new element /* initialize the new element
@ -166,20 +162,15 @@ gst_template_match_class_init (GstTemplateMatchClass * klass)
* initialize instance structure * initialize instance structure
*/ */
static void static void
gst_template_match_init (GstTemplateMatch * filter, gst_template_match_init (GstTemplateMatch * filter)
GstTemplateMatchClass * gclass)
{ {
filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink"); filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
gst_pad_set_setcaps_function (filter->sinkpad, gst_pad_set_event_function (filter->sinkpad,
GST_DEBUG_FUNCPTR (gst_template_match_set_caps)); GST_DEBUG_FUNCPTR (gst_template_match_handle_sink_event));
gst_pad_set_getcaps_function (filter->sinkpad,
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
gst_pad_set_chain_function (filter->sinkpad, gst_pad_set_chain_function (filter->sinkpad,
GST_DEBUG_FUNCPTR (gst_template_match_chain)); GST_DEBUG_FUNCPTR (gst_template_match_chain));
filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src"); filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
gst_pad_set_getcaps_function (filter->srcpad,
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
@ -260,25 +251,35 @@ gst_template_match_get_property (GObject * object, guint prop_id,
/* this function handles the link with other elements */ /* this function handles the link with other elements */
static gboolean static gboolean
gst_template_match_set_caps (GstPad * pad, GstCaps * caps) gst_template_match_handle_sink_event (GstPad * pad, GstObject * parent,
GstEvent * event)
{ {
GstTemplateMatch *filter; GstTemplateMatch *filter;
GstPad *otherpad; GstVideoInfo info;
gint width, height; gboolean res = TRUE;
GstStructure *structure;
filter = GST_TEMPLATE_MATCH (gst_pad_get_parent (pad)); filter = GST_TEMPLATE_MATCH (parent);
structure = gst_caps_get_structure (caps, 0); switch (GST_EVENT_TYPE (event)) {
gst_structure_get_int (structure, "width", &width); case GST_EVENT_CAPS:
gst_structure_get_int (structure, "height", &height); {
GstCaps *caps;
gst_event_parse_caps (event, &caps);
gst_video_info_from_caps (&info, caps);
filter->cvImage = filter->cvImage =
cvCreateImageHeader (cvSize (width, height), IPL_DEPTH_8U, 3); cvCreateImageHeader (cvSize (info.width, info.height), IPL_DEPTH_8U,
3);
break;
}
default:
break;
}
res = gst_pad_event_default (pad, parent, event);
return res;
otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad;
gst_object_unref (filter);
return gst_pad_set_caps (otherpad, caps);
} }
static void static void
@ -297,29 +298,32 @@ gst_template_match_finalize (GObject * object)
cvReleaseImage (&filter->cvTemplateImage); cvReleaseImage (&filter->cvTemplateImage);
} }
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); G_OBJECT_CLASS (gst_template_match_parent_class)->finalize (object);
} }
/* chain function /* chain function
* this function does the actual processing * this function does the actual processing
*/ */
static GstFlowReturn static GstFlowReturn
gst_template_match_chain (GstPad * pad, GstBuffer * buf) gst_template_match_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{ {
GstTemplateMatch *filter; GstTemplateMatch *filter;
CvPoint best_pos; CvPoint best_pos;
double best_res; double best_res;
GstMapInfo info;
filter = GST_TEMPLATE_MATCH (GST_OBJECT_PARENT (pad)); filter = GST_TEMPLATE_MATCH (parent);
/* FIXME Why template == NULL returns OK? /* FIXME Why template == NULL returns OK?
* shouldn't it be a passthrough instead? */ * shouldn't it be a passthrough instead? */
if ((!filter) || (!buf) || filter->template == NULL) { if ((!filter) || (!buf) || filter->template == NULL) {
return GST_FLOW_OK; return GST_FLOW_OK;
} }
GST_DEBUG_OBJECT (filter, "Buffer size %u ", GST_BUFFER_SIZE (buf)); GST_DEBUG_OBJECT (filter, "Buffer size %u ", gst_buffer_get_size (buf));
filter->cvImage->imageData = (char *) GST_BUFFER_DATA (buf); buf = gst_buffer_make_writable (buf);
gst_buffer_map (buf, &info, GST_MAP_READWRITE);
filter->cvImage->imageData = (char *) info.data;
if (!filter->cvDistImage) { if (!filter->cvDistImage) {
if (filter->cvTemplateImage->width > filter->cvImage->width) { if (filter->cvTemplateImage->width > filter->cvImage->width) {

View file

@ -51,7 +51,7 @@
* <refsect2> * <refsect2>
* <title>Example launch line</title> * <title>Example launch line</title>
* |[ * |[
* gst-launch-0.10 videotestsrc ! ffmpegcolorspace ! opencvtextoverlay text="Opencv Text Overlay " ! ffmpegcolorspace ! xvimagesink * gst-launch-1.0 videotestsrc ! videoconvert ! opencvtextoverlay text="Opencv Text Overlay " ! videoconvert ! xvimagesink
* ]| * ]|
* </refsect2> * </refsect2>
*/ */
@ -68,7 +68,7 @@
GST_DEBUG_CATEGORY_STATIC (gst_opencv_text_overlay_debug); GST_DEBUG_CATEGORY_STATIC (gst_opencv_text_overlay_debug);
#define GST_CAT_DEFAULT gst_opencv_opencv_text_overlay_debug #define GST_CAT_DEFAULT gst_opencv_opencv_text_overlay_debug
#define DEFAULT_PROP_TEXT "" #define DEFAULT_PROP_TEXT "Opencv Text Overlay"
#define DEFAULT_PROP_WIDTH 1 #define DEFAULT_PROP_WIDTH 1
#define DEFAULT_PROP_HEIGHT 1 #define DEFAULT_PROP_HEIGHT 1
#define DEFAULT_PROP_XPOS 50 #define DEFAULT_PROP_XPOS 50
@ -106,28 +106,26 @@ enum
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB"))
); );
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB"))
); );
GST_BOILERPLATE (GstOpencvTextOverlay, gst_opencv_text_overlay, GstElement, G_DEFINE_TYPE (GstOpencvTextOverlay, gst_opencv_text_overlay, GST_TYPE_ELEMENT);
GST_TYPE_ELEMENT);
static void gst_opencv_text_overlay_set_property (GObject * object, static void gst_opencv_text_overlay_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec); guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_opencv_text_overlay_get_property (GObject * object, static void gst_opencv_text_overlay_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec); guint prop_id, GValue * value, GParamSpec * pspec);
static gboolean gst_opencv_text_overlay_set_caps (GstPad * pad, GstCaps * caps); static gboolean gst_opencv_text_overlay_handle_sink_event (GstPad * pad,
GstObject * parent, GstEvent * event);
static GstFlowReturn gst_opencv_text_overlay_chain (GstPad * pad, static GstFlowReturn gst_opencv_text_overlay_chain (GstPad * pad,
GstBuffer * buf); GstObject * parent, GstBuffer * buf);
/* Clean up */ /* Clean up */
static void static void
@ -139,27 +137,7 @@ gst_opencv_text_overlay_finalize (GObject * obj)
cvReleaseImage (&filter->cvImage); cvReleaseImage (&filter->cvImage);
} }
G_OBJECT_CLASS (parent_class)->finalize (obj); G_OBJECT_CLASS (gst_opencv_text_overlay_parent_class)->finalize (obj);
}
/* GObject vmethod implementations */
static void
gst_opencv_text_overlay_base_init (gpointer gclass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
gst_element_class_set_details_simple (element_class,
"opencvtextoverlay",
"Filter/Effect/Video",
"Write text on the top of video", "sreerenj<bsreerenj@gmail.com>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
} }
/* initialize the opencvtextoverlay's class */ /* initialize the opencvtextoverlay's class */
@ -168,16 +146,15 @@ gst_opencv_text_overlay_class_init (GstOpencvTextOverlayClass * klass)
{ {
GObjectClass *gobject_class; GObjectClass *gobject_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
parent_class = g_type_class_peek_parent (klass);
gobject_class->finalize = gobject_class->finalize =
GST_DEBUG_FUNCPTR (gst_opencv_text_overlay_finalize); GST_DEBUG_FUNCPTR (gst_opencv_text_overlay_finalize);
gobject_class->set_property = gst_opencv_text_overlay_set_property; gobject_class->set_property = gst_opencv_text_overlay_set_property;
gobject_class->get_property = gst_opencv_text_overlay_get_property; gobject_class->get_property = gst_opencv_text_overlay_get_property;
g_object_class_install_property (gobject_class, PROP_TEXT, g_object_class_install_property (gobject_class, PROP_TEXT,
g_param_spec_string ("text", "text", g_param_spec_string ("text", "text",
"Text to be display.", DEFAULT_PROP_TEXT, "Text to be display.", DEFAULT_PROP_TEXT,
@ -223,6 +200,16 @@ gst_opencv_text_overlay_class_init (GstOpencvTextOverlayClass * klass)
"Sets the width of fonts", 1.0, 5.0, "Sets the width of fonts", 1.0, 5.0,
DEFAULT_WIDTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); DEFAULT_WIDTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_set_details_simple (element_class,
"opencvtextoverlay",
"Filter/Effect/Video",
"Write text on the top of video", "sreerenj<bsreerenj@gmail.com>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
} }
/* initialize the new element /* initialize the new element
@ -231,23 +218,22 @@ gst_opencv_text_overlay_class_init (GstOpencvTextOverlayClass * klass)
* initialize instance structure * initialize instance structure
*/ */
static void static void
gst_opencv_text_overlay_init (GstOpencvTextOverlay * filter, gst_opencv_text_overlay_init (GstOpencvTextOverlay * filter)
GstOpencvTextOverlayClass * gclass)
{ {
filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink"); filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
gst_pad_set_setcaps_function (filter->sinkpad, GST_PAD_SET_PROXY_CAPS (filter->sinkpad);
GST_DEBUG_FUNCPTR (gst_opencv_text_overlay_set_caps)); gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
gst_pad_set_getcaps_function (filter->sinkpad,
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); gst_pad_set_event_function (filter->sinkpad,
GST_DEBUG_FUNCPTR (gst_opencv_text_overlay_handle_sink_event));
gst_pad_set_chain_function (filter->sinkpad, gst_pad_set_chain_function (filter->sinkpad,
GST_DEBUG_FUNCPTR (gst_opencv_text_overlay_chain)); GST_DEBUG_FUNCPTR (gst_opencv_text_overlay_chain));
filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src"); filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
gst_pad_set_getcaps_function (filter->srcpad, GST_PAD_SET_PROXY_CAPS (filter->srcpad);
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
filter->textbuf = g_strdup (DEFAULT_PROP_TEXT); filter->textbuf = g_strdup (DEFAULT_PROP_TEXT);
filter->width = DEFAULT_PROP_WIDTH; filter->width = DEFAULT_PROP_WIDTH;
filter->height = DEFAULT_PROP_HEIGHT; filter->height = DEFAULT_PROP_HEIGHT;
@ -343,44 +329,59 @@ gst_opencv_text_overlay_get_property (GObject * object, guint prop_id,
} }
} }
/* GstElement vmethod implementations */
/* this function handles the link with other elements */
static gboolean static gboolean
gst_opencv_text_overlay_set_caps (GstPad * pad, GstCaps * caps) gst_opencv_text_overlay_handle_sink_event (GstPad * pad, GstObject * parent,
GstEvent * event)
{ {
GstOpencvTextOverlay *filter; GstOpencvTextOverlay *filter;
GstPad *otherpad;
gint width, height; gint width, height;
GstStructure *structure; GstStructure *structure;
gboolean res = TRUE;
filter = GST_OPENCV_TEXT_OVERLAY (gst_pad_get_parent (pad)); filter = GST_OPENCV_TEXT_OVERLAY (parent);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_CAPS:
{
GstCaps *caps;
gst_event_parse_caps (event, &caps);
structure = gst_caps_get_structure (caps, 0); structure = gst_caps_get_structure (caps, 0);
gst_structure_get_int (structure, "width", &width); gst_structure_get_int (structure, "width", &width);
gst_structure_get_int (structure, "height", &height); gst_structure_get_int (structure, "height", &height);
if (!filter->cvImage) {
filter->cvImage = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 3); filter->cvImage = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 3);
filter->cvStorage = cvCreateMemStorage (0); filter->cvStorage = cvCreateMemStorage (0);
otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad;
gst_object_unref (filter);
return gst_pad_set_caps (otherpad, caps);
} }
break;
}
default:
break;
}
res = gst_pad_event_default (pad, parent, event);
return res;
}
/* chain function /* chain function
* this function does the actual processing * this function does the actual processing
*/ */
static GstFlowReturn static GstFlowReturn
gst_opencv_text_overlay_chain (GstPad * pad, GstBuffer * buf) gst_opencv_text_overlay_chain (GstPad * pad, GstObject * parent,
GstBuffer * buf)
{ {
GstOpencvTextOverlay *filter; GstOpencvTextOverlay *filter;
GstMapInfo map_info;
guint8 *data;
filter = GST_OPENCV_TEXT_OVERLAY (GST_OBJECT_PARENT (pad)); filter = GST_OPENCV_TEXT_OVERLAY (parent);
filter->cvImage->imageData = (char *) GST_BUFFER_DATA (buf); gst_buffer_map (buf, &map_info, GST_MAP_READ);
data = map_info.data;
filter->cvImage->imageData = (char *) data;
cvInitFont (&(filter->font), CV_FONT_VECTOR0, filter->width, filter->height, cvInitFont (&(filter->font), CV_FONT_VECTOR0, filter->width, filter->height,
0, filter->thickness, 0); 0, filter->thickness, 0);
@ -390,6 +391,7 @@ gst_opencv_text_overlay_chain (GstPad * pad, GstBuffer * buf)
filter->ypos), &(filter->font), cvScalar (filter->colorR, filter->ypos), &(filter->font), cvScalar (filter->colorR,
filter->colorG, filter->colorB, 0)); filter->colorG, filter->colorB, 0));
gst_buffer_unmap (buf, &map_info);
return gst_pad_push (filter->srcpad, buf); return gst_pad_push (filter->srcpad, buf);
} }

View file

@ -47,7 +47,7 @@
#define __GST_OPENCV_TEXT_OVERLAY_H__ #define __GST_OPENCV_TEXT_OVERLAY_H__
#include <gst/gst.h> #include <gst/gst.h>
#include "gstopencvutils.h"
G_BEGIN_DECLS G_BEGIN_DECLS
/* #defines don't like whitespacey bits */ /* #defines don't like whitespacey bits */