summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac4
-rw-r--r--ext/opencv/Makefile.am7
-rw-r--r--ext/opencv/gsthanddetect.c220
-rw-r--r--ext/opencv/gsthanddetect.h22
-rw-r--r--ext/opencv/gstopencv.c4
-rw-r--r--tests/examples/opencv/Makefile.am7
-rw-r--r--tests/examples/opencv/gsthanddetect_test.c339
7 files changed, 261 insertions, 342 deletions
diff --git a/configure.ac b/configure.ac
index 89a967dcb..67a341c37 100644
--- a/configure.ac
+++ b/configure.ac
@@ -33,6 +33,10 @@ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],
[AM_DEFAULT_VERBOSITY=1
AC_SUBST(AM_DEFAULT_VERBOSITY)])
+dnl define GST_DATADIR
+AS_AC_EXPAND(DATADIR, $datadir)
+AC_DEFINE_UNQUOTED(GST_DATADIR, "$DATADIR", [data dir])
+
dnl our libraries and install dirs use GST_API_VERSION in the filename
dnl to allow side-by-side installation of different API versions
GST_API_VERSION=1.0
diff --git a/ext/opencv/Makefile.am b/ext/opencv/Makefile.am
index c02037b22..4bcc78ed2 100644
--- a/ext/opencv/Makefile.am
+++ b/ext/opencv/Makefile.am
@@ -14,6 +14,7 @@ libgstopencv_la_SOURCES = gstopencv.c \
gstedgedetect.c \
gstfaceblur.c \
gstfacedetect.c \
+ gsthanddetect.c \
gstpyramidsegment.c \
gsttemplatematch.c \
gsttextoverlay.c \
@@ -50,9 +51,15 @@ noinst_HEADERS = gstopencvvideofilter.h gstopencvutils.h \
gstedgedetect.h \
gstfaceblur.h \
gstfacedetect.h \
+ gsthanddetect.h \
gstpyramidsegment.h \
gsttemplatematch.h \
gsttextoverlay.h \
gstmotioncells.h \
motioncells_wrapper.h \
MotionCells.h
+
+opencv_haarcascadesdir = $(datadir)/gstreamer-$(GST_API_VERSION)/opencv_haarcascades
+opencv_haarcascades_DATA = fist.xml palm.xml
+
+EXTRA_DIST = $(opencv_haarcascades_DATA)
diff --git a/ext/opencv/gsthanddetect.c b/ext/opencv/gsthanddetect.c
index 223a18595..57885c7ba 100644
--- a/ext/opencv/gsthanddetect.c
+++ b/ext/opencv/gsthanddetect.c
@@ -1,6 +1,7 @@
/*
* GStreamer hand gesture detection plugins
* Copyright (C) 2012 Andol Li <<andol@andol.info>>
+ * Copyright (C) 2013 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -49,8 +50,8 @@
* <refsect2>
* <title>Example launch line</title>
* |[
- * gst-launch autovideosrc ! ffmpegcolorspace ! "video/x-raw-rgb, width=320, height=240" ! \
- videoscale ! handdetect ! ffmpegcolorspace ! xvimagesink
+ * gst-launch autovideosrc ! videoconvert ! "video/x-raw, formt=RGB, width=320, height=240" ! \
+ videoscale ! handdetect ! videoconvert ! xvimagesink
* ]|
* </refsect2>
*/
@@ -58,23 +59,18 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-/* interfaces */
-#include <gst/interfaces/navigation.h>
+
/* element header */
#include "gsthanddetect.h"
-/* gst */
-#include <gst/gst.h>
-#include <gst/video/video.h>
#include "gstopencvutils.h"
-/* debugging */
-#include <gst/gstinfo.h>
GST_DEBUG_CATEGORY_STATIC (gst_handdetect_debug);
#define GST_CAT_DEFAULT gst_handdetect_debug
/* define HAAR files */
-#define HAAR_FILE_FIST "/usr/local/share/opencv/haarcascades/fist.xml"
-#define HAAR_FILE_PALM "/usr/local/share/opencv/haarcascades/palm.xml"
+#define HAAR_CASCADES_DIR GST_DATADIR "/gstreamer-"GST_API_VERSION"/opencv_haarcascades/"
+#define HAAR_FILE_FIST HAAR_CASCADES_DIR "fist.xml"
+#define HAAR_FILE_PALM HAAR_CASCADES_DIR "palm.xml"
/* Filter signals and args */
enum
@@ -99,12 +95,12 @@ enum
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
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",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB)
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB"))
);
static void gst_handdetect_set_property (GObject * object, guint prop_id,
@@ -119,60 +115,22 @@ static GstFlowReturn gst_handdetect_transform_ip (GstOpencvVideoFilter *
static void gst_handdetect_load_profile (GstHanddetect * filter);
-static void gst_handdetect_init_interfaces (GType type);
-static void
-gst_handdetect_implements_interface_init (GstImplementsInterfaceClass * klass);
-static void gst_handdetect_navigation_interface_init (gpointer g_iface,
- gpointer iface_data);
-static gboolean gst_handdetect_interface_supported (GstImplementsInterface *
- iface, GType type);
+static void gst_handdetect_navigation_interface_init (GstNavigationInterface *
+ iface);
static void gst_handdetect_navigation_send_event (GstNavigation * navigation,
GstStructure * structure);
-static gboolean gst_handdetect_handle_pad_event (GstPad * pad,
- GstEvent * event);
-GST_BOILERPLATE_FULL (GstHanddetect, gst_handdetect, GstOpencvVideoFilter,
- GST_TYPE_OPENCV_VIDEO_FILTER, gst_handdetect_init_interfaces);
+G_DEFINE_TYPE_WITH_CODE (GstHanddetect, gst_handdetect,
+ GST_TYPE_OPENCV_VIDEO_FILTER,
+ G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION,
+ gst_handdetect_navigation_interface_init););
static void
-gst_handdetect_init_interfaces (GType type)
+gst_handdetect_navigation_interface_init (GstNavigationInterface * iface)
{
- static const GInterfaceInfo iface_info = {
- (GInterfaceInitFunc) gst_handdetect_implements_interface_init,
- NULL,
- NULL,
- };
- g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE,
- &iface_info);
- static const GInterfaceInfo navigation_info = {
- (GInterfaceInitFunc) gst_handdetect_navigation_interface_init,
- NULL,
- NULL,
- };
- g_type_add_interface_static (type, GST_TYPE_NAVIGATION, &navigation_info);
-}
-
-static void
-gst_handdetect_navigation_interface_init (gpointer g_iface, gpointer iface_data)
-{
- GstNavigationInterface *iface = (GstNavigationInterface *) g_iface;
iface->send_event = gst_handdetect_navigation_send_event;
}
-static gboolean
-gst_handdetect_interface_supported (GstImplementsInterface * iface, GType type)
-{
- if (type == GST_TYPE_NAVIGATION)
- return TRUE;
- return FALSE;
-}
-
-static void
-gst_handdetect_implements_interface_init (GstImplementsInterfaceClass * klass)
-{
- klass->supported = gst_handdetect_interface_supported;
-}
-
/* FIXME: this function used to parse the region of interests coordinates
* sending from applications when the hand gestures reach the defined regions of interests,
* at this moment this function is not doing anything significantly
@@ -193,60 +151,9 @@ gst_handdetect_navigation_send_event (GstNavigation * navigation,
}
}
-/* handle element pad event */
-/* no PRACTICAL USE at the moment
- * this function is used to debug the fist-move/palm-move event
- * will CHANGE in the future
- */
-static gboolean
-gst_handdetect_handle_pad_event (GstPad * pad, GstEvent * event)
-{
- const GstStructure *s = gst_event_get_structure (event);
- const gchar *name = gst_structure_get_string (s, "event");
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_EOS:
- break;
- case GST_EVENT_NAVIGATION:{
- if (g_str_equal (name, "fist-move")) {
- GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)),
- "Fist-move event\n ");
- uint x, y;
- gst_structure_get_uint (s, "x", &x);
- gst_structure_get_uint (s, "y", &y);
- GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)),
- "Fist Pos:[%d, %d]\n", x, y);
- } else if (g_str_equal (name, "palm-move")) {
- GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)),
- "Palm-move event\n ");
- uint x, y;
- gst_structure_get_uint (s, "x", &x);
- gst_structure_get_uint (s, "y", &y);
- GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)),
- "Palm Pos:[%d, %d]\n", x, y);
- } else if (g_str_equal (name, "mouse-move")) {
- gdouble x, y;
- gst_structure_get_double (s, "pointer_x", &x);
- gst_structure_get_double (s, "pointer_y", &y);
- GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)),
- "Mouse-move [%f, %f]\n", x, y);
- } else if (g_str_equal (name, "mouse-button-press")) {
- GST_DEBUG ("Mouse botton press\n");
- } else if (g_str_equal (name, "mouse-button-release")) {
- GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)),
- "Mouse button release\n");
- }
- break;
- }
- default:
- break;
- }
- return gst_pad_event_default (pad, event);
-}
-
/* clean opencv images and parameters */
static void
-gst_handdetect_finalise (GObject * obj)
+gst_handdetect_finalize (GObject * obj)
{
GstHanddetect *filter = GST_HANDDETECT (obj);
@@ -257,23 +164,7 @@ gst_handdetect_finalise (GObject * obj)
g_free (filter->profile_fist);
g_free (filter->profile_palm);
- G_OBJECT_CLASS (parent_class)->finalize (obj);
-}
-
-/* GObject vmethod implementations */
-static void
-gst_handdetect_base_init (gpointer gclass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
-
- gst_element_class_set_details_simple (element_class,
- "hand detect",
- "Filter/Effect/Video",
- "Performs hand gesture detection on videos, providing detected hand positions via bus message and navigation event, and deals with hand gesture events",
- "Andol Li <<andol@andol.info>>");
-
- gst_element_class_add_static_pad_template (element_class, &src_factory);
- gst_element_class_add_static_pad_template (element_class, &sink_factory);
+ G_OBJECT_CLASS (gst_handdetect_parent_class)->finalize (obj);
}
/* initialise the HANDDETECT class */
@@ -283,13 +174,14 @@ gst_handdetect_class_init (GstHanddetectClass * klass)
GObjectClass *gobject_class;
GstOpencvVideoFilterClass *gstopencvbasefilter_class;
+ GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gobject_class = (GObjectClass *) klass;
gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass;
gstopencvbasefilter_class->cv_trans_ip_func = gst_handdetect_transform_ip;
gstopencvbasefilter_class->cv_set_caps = gst_handdetect_set_caps;
- gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_handdetect_finalise);
+ gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_handdetect_finalize);
gobject_class->set_property = gst_handdetect_set_property;
gobject_class->get_property = gst_handdetect_get_property;
@@ -342,6 +234,18 @@ gst_handdetect_class_init (GstHanddetectClass * klass)
"HEIGHT of left-top pointer in region of interest \nGestures in the defined region of interest will emit messages",
0, UINT_MAX, 0, G_PARAM_READWRITE)
);
+
+ gst_element_class_set_static_metadata (element_class,
+ "handdetect",
+ "Filter/Effect/Video",
+ "Performs hand gesture detection on videos, providing detected hand positions via bus message and navigation event, and deals with hand gesture events",
+ "Andol Li <andol@andol.info>");
+
+ 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));
+
}
/* initialise the new element
@@ -350,13 +254,8 @@ gst_handdetect_class_init (GstHanddetectClass * klass)
* initialise instance structure
*/
static void
-gst_handdetect_init (GstHanddetect * filter, GstHanddetectClass * gclass)
+gst_handdetect_init (GstHanddetect * filter)
{
- GstBaseTransform *trans = GST_BASE_TRANSFORM_CAST (filter);
-
- gst_pad_set_event_function (trans->srcpad,
- GST_DEBUG_FUNCPTR (gst_handdetect_handle_pad_event));
-
filter->profile_fist = g_strdup (HAAR_FILE_FIST);
filter->profile_palm = g_strdup (HAAR_FILE_PALM);
filter->roi_x = 0;
@@ -481,13 +380,17 @@ gst_handdetect_transform_ip (GstOpencvVideoFilter * transform,
GstBuffer * buffer, IplImage * img)
{
GstHanddetect *filter = GST_HANDDETECT (transform);
+ GstMapInfo info;
CvSeq *hands;
CvRect *r;
GstStructure *s;
GstMessage *m;
int i;
- filter->cvImage->imageData = (char *) GST_BUFFER_DATA (buffer);
+ buffer = gst_buffer_make_writable (buffer);
+ gst_buffer_map (buffer, &info, GST_MAP_READWRITE);
+
+ filter->cvImage->imageData = (char *) info.data;
/* 320 x 240 is with the best detect accuracy, if not, give info */
if (filter->cvImage->width != 320 || filter->cvImage->height != 240)
GST_INFO_OBJECT (filter,
@@ -511,6 +414,9 @@ gst_handdetect_transform_ip (GstOpencvVideoFilter * transform,
/* if FIST gesture detected */
if (hands && hands->total > 0) {
+ int min_distance, distance;
+ CvRect temp_r;
+ CvPoint c;
/* set frame buffer writable */
if (filter->display) {
buffer = gst_buffer_make_writable (buffer);
@@ -522,15 +428,15 @@ gst_handdetect_transform_ip (GstOpencvVideoFilter * transform,
* best_r => best hand in this frame
*/
/* set min_distance for init comparison */
- int min_distance = filter->cvImage->width + filter->cvImage->height;
+ min_distance = filter->cvImage->width + filter->cvImage->height;
/* Init filter->prev_r */
- CvRect temp_r = cvRect (0, 0, 0, 0);
+ temp_r = cvRect (0, 0, 0, 0);
if (filter->prev_r == NULL)
filter->prev_r = &temp_r;
/* Get the best FIST gesture */
for (i = 0; i < (hands ? hands->total : 0); i++) {
r = (CvRect *) cvGetSeqElem (hands, i);
- int distance = (int) sqrt (pow ((r->x - filter->prev_r->x),
+ distance = (int) sqrt (pow ((r->x - filter->prev_r->x),
2) + pow ((r->y - filter->prev_r->y), 2));
if (distance <= min_distance) {
min_distance = distance;
@@ -541,8 +447,7 @@ gst_handdetect_transform_ip (GstOpencvVideoFilter * transform,
filter->prev_r = (CvRect *) filter->best_r;
/* send msg to app/bus if the detected gesture falls in the region of interest */
/* get center point of gesture */
- CvPoint c =
- cvPoint (filter->best_r->x + filter->best_r->width / 2,
+ c = cvPoint (filter->best_r->x + filter->best_r->width / 2,
filter->best_r->y + filter->best_r->height / 2);
/* send message:
* if the center point is in the region of interest, OR,
@@ -602,6 +507,9 @@ gst_handdetect_transform_ip (GstOpencvVideoFilter * transform,
);
/* if PALM detected */
if (hands && hands->total > 0) {
+ int min_distance, distance;
+ CvRect temp_r;
+ CvPoint c;
/* set frame buffer writable */
if (filter->display) {
buffer = gst_buffer_make_writable (buffer);
@@ -613,15 +521,15 @@ gst_handdetect_transform_ip (GstOpencvVideoFilter * transform,
* best_r => best hand in this frame
*/
/* suppose a min_distance for init comparison */
- int min_distance = filter->cvImage->width + filter->cvImage->height;
+ min_distance = filter->cvImage->width + filter->cvImage->height;
/* Init filter->prev_r */
- CvRect temp_r = cvRect (0, 0, 0, 0);
+ temp_r = cvRect (0, 0, 0, 0);
if (filter->prev_r == NULL)
filter->prev_r = &temp_r;
/* Get the best PALM gesture */
for (i = 0; i < (hands ? hands->total : 0); i++) {
r = (CvRect *) cvGetSeqElem (hands, i);
- int distance = (int) sqrt (pow ((r->x - filter->prev_r->x),
+ distance = (int) sqrt (pow ((r->x - filter->prev_r->x),
2) + pow ((r->y - filter->prev_r->y), 2));
if (distance <= min_distance) {
min_distance = distance;
@@ -633,8 +541,7 @@ gst_handdetect_transform_ip (GstOpencvVideoFilter * transform,
/* send msg to app/bus if the detected gesture falls in the region of interest */
/* get center point of gesture */
- CvPoint c =
- cvPoint (filter->best_r->x + filter->best_r->width / 2,
+ c = cvPoint (filter->best_r->x + filter->best_r->width / 2,
filter->best_r->y + filter->best_r->height / 2);
/* send message:
* if the center point is in the region of interest, OR,
@@ -700,7 +607,7 @@ gst_handdetect_transform_ip (GstOpencvVideoFilter * transform,
}
}
}
-
+ gst_buffer_unmap (buffer, &info);
/* Push out the incoming buffer */
return GST_FLOW_OK;
}
@@ -731,7 +638,7 @@ gst_handdetect_load_profile (GstHanddetect * filter)
* Initialize the plug-in itself
* Register the element factories and other features
*/
-static gboolean
+gboolean
gst_handdetect_plugin_init (GstPlugin * plugin)
{
GST_DEBUG_CATEGORY_INIT (gst_handdetect_debug,
@@ -741,22 +648,3 @@ gst_handdetect_plugin_init (GstPlugin * plugin)
return gst_element_register (plugin, "handdetect", GST_RANK_NONE,
GST_TYPE_HANDDETECT);
}
-
-/* PACKAGE: this is usually set by autotools depending on some _INIT macro
- * in configure.ac and then written into and defined in config.h, but we can
- * just set it ourselves here in case someone doesn't use autotools to
- * compile this code. GST_PLUGIN_DEFINE needs PACKAGE to be defined.
- */
-#ifndef PACKAGE
-#define PACKAGE "gst_handdetect"
-#endif
-
-/*
- * Gstreamer looks for this structure to register handdetect
- */
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "handdetect",
- "Detect hand gestures for media operations",
- gst_handdetect_plugin_init, VERSION, "LGPL", "GStreamer",
- "http://gstreamer.net/")
diff --git a/ext/opencv/gsthanddetect.h b/ext/opencv/gsthanddetect.h
index 1d4a6831d..9fb69a6a1 100644
--- a/ext/opencv/gsthanddetect.h
+++ b/ext/opencv/gsthanddetect.h
@@ -1,8 +1,7 @@
/*
* GStreamer
- * Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
- * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* Copyright (C) 2012 andol li <<andol@andol.info>>
+ * Copyright (c) 2013 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -46,20 +45,15 @@
#ifndef __GST_HANDDETECT_H__
#define __GST_HANDDETECT_H__
-#ifndef VERSION
-#define VERSION "0.10.36" /* for GST_PLUGIN_DEFINE use */
-#endif
-
-#include <math.h>
-#include <string.h>
-#include <stdlib.h>
#include <gst/gst.h>
-#include <gst/video/gstvideofilter.h>
+#include <gst/video/video.h>
+#include <gst/video/navigation.h>
+
#include "gstopencvvideofilter.h"
/* opencv */
-#include <opencv/cv.h>
-#include <opencv/cxcore.h>
-#include <opencv/highgui.h>
+#include <cv.h>
+#include <cxcore.h>
+#include <highgui.h>
#if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2)
#include <opencv2/objdetect/objdetect.hpp>
#endif
@@ -113,5 +107,7 @@ struct _GstHanddetectClass
GType gst_handdetect_get_type (void);
+gboolean gst_handdetect_plugin_init (GstPlugin * plugin);
+
G_END_DECLS
#endif /* __GST_HANDDETECT_H__ */
diff --git a/ext/opencv/gstopencv.c b/ext/opencv/gstopencv.c
index afcdb41ab..289192240 100644
--- a/ext/opencv/gstopencv.c
+++ b/ext/opencv/gstopencv.c
@@ -36,6 +36,7 @@
#include "gstpyramidsegment.h"
#include "gsttemplatematch.h"
#include "gsttextoverlay.h"
+#include "gsthanddetect.h"
static gboolean
plugin_init (GstPlugin * plugin)
@@ -79,6 +80,9 @@ plugin_init (GstPlugin * plugin)
if (!gst_opencv_text_overlay_plugin_init (plugin))
return FALSE;
+ if (!gst_handdetect_plugin_init (plugin))
+ return FALSE;
+
return TRUE;
}
diff --git a/tests/examples/opencv/Makefile.am b/tests/examples/opencv/Makefile.am
index 4241e9e57..9db9da4bb 100644
--- a/tests/examples/opencv/Makefile.am
+++ b/tests/examples/opencv/Makefile.am
@@ -1,11 +1,16 @@
-noinst_PROGRAMS = gstmotioncells_dynamic_test
+noinst_PROGRAMS = gstmotioncells_dynamic_test \
+ gsthanddetect_test
gstmotioncells_dynamic_test_SOURCES = \
gstmotioncells_dynamic_test.c \
gst_element_print_properties.c
+gsthanddetect_test_SOURCES = gsthanddetect_test.c
+
gstmotioncells_dynamic_test_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS)
gstmotioncells_dynamic_test_LDFLAGS = $(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GSTPB_BASE_LIBS)
+gsthanddetect_test_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS)
+gsthanddetect_test_LDFLAGS = $(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GSTPB_BASE_LIBS)
noinst_HEADERS = \
gstmotioncells_dynamic_test.h \
gst_element_print_properties.h
diff --git a/tests/examples/opencv/gsthanddetect_test.c b/tests/examples/opencv/gsthanddetect_test.c
index 2a2187bb7..05e11ed06 100644
--- a/tests/examples/opencv/gsthanddetect_test.c
+++ b/tests/examples/opencv/gsthanddetect_test.c
@@ -1,174 +1,189 @@
-/*
- *============================================================================
- *Name : gsthanddetect_app.c
- *Author : Andol Li, andol@andol.info
- *Version : 0.1
- *Copyright : @2012, gstreamer
- *Description : gsteramer handdetect plugin demo application in C, part work of GSoc 2012 project
- *============================================================================
+/* GStreamer
+ * Copyright (C) 2012 Andol Li <andol@andol.info>
+ *
+ * gsthanddetect_test: gsteramer handdetect plugin demo application,
+ * part work of GSoc 2012 project
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gst/gst.h>
-#include <glib.h>
-#include <glib-object.h>
-#define PROFILE_FIST "/usr/local/share/opencv/haarcascades/fist.xml"
-#define PROFILE_PALM "/usr/local/share/opencv/haarcascades/palm.xml"
+GstElement *playbin, *pipeline;
+GstElement *v4l2src, *videoscale, *videoconvert_in, *handdetect,
+ *videoconvert_out, *xvimagesink;
-GstElement *playbin,
- *pipeline,
- *v4l2src, *videoscale, *ffmpegcolorspace_in, *handdetect, *ffmpegcolorspace_out, *xvimagesink;
-
-static GstBusSyncHandler
-bus_sync_handler(GstBus *bus, GstMessage *message, GstPipeline *pipeline)
+static GstBusSyncReply
+bus_sync_handler (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
{
- /* select msg */
- if(GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT ||
- !gst_structure_has_name(message->structure, "hand-gesture") )
- return GST_BUS_PASS;
-
- /* parse msg structure */
- const GstStructure *structure = message->structure;
-
- /* if PALM gesture detected */
- if (structure &&
- strcmp (gst_structure_get_name (structure), "hand-gesture") == 0 &&
- strcmp (gst_structure_get_string (structure, "gesture"), "palm") == 0) {
- /* media operation - closed palm to stop media play*/
- gst_element_set_state (playbin, GST_STATE_PAUSED);
- }
-
- /* if FIST gesture detected */
- if (structure &&
- strcmp (gst_structure_get_name (structure), "hand-gesture") == 0 &&
- strcmp (gst_structure_get_string (structure, "gesture"), "fist") == 0){
- /* print message type and structure name */
- g_print("%s{{%s}}\n", gst_message_type_get_name(message->type), gst_structure_get_name(structure));
- /* print msg structure names&values */
- int i;
- for(i = 0; i < gst_structure_n_fields(structure); i++){
- const gchar *name = gst_structure_nth_field_name(structure, i);
- GType type = gst_structure_get_field_type(structure, name);
- const GValue *value = gst_structure_get_value(structure, name);
- type == G_TYPE_STRING ?
- g_print("-%s[%s]{%s}\n", name, g_type_name(type), g_value_get_string(value)) :
- g_print("-%s[%s]{%d}\n", name, g_type_name(type), g_value_get_uint(value));
- }
- g_print("\n");
-
- /* get X,Y positions in frame */
- const GValue *x_value = gst_structure_get_value(structure, "x");
- gint x = g_value_get_uint(x_value);
- const GValue *y_value = gst_structure_get_value(structure, "y");
- gint y = g_value_get_uint(y_value);
-
- /* set object volumes [0-10] based on Y */
- g_object_set(G_OBJECT(playbin), "volume", (gdouble)(10 - y/24 ), NULL);
-
- /* seek playback positions */
- gint64 position, length;
- GstFormat format = GST_FORMAT_TIME;
- gst_element_query_duration(playbin, &format, &length);
- /* Width = 320 is specified in caps */
- position = (gint64) length * x / 320;
- gst_element_set_state(playbin, GST_STATE_PAUSED);
- gst_element_seek(GST_ELEMENT(playbin),
- 1.0,
- format,
- GST_SEEK_FLAG_FLUSH,
- GST_SEEK_TYPE_SET,
- position,
- GST_SEEK_TYPE_NONE,
- GST_CLOCK_TIME_NONE );
- gst_element_set_state(GST_ELEMENT(playbin), GST_STATE_PLAYING);
- }
-
- gst_message_unref(message);
- return GST_BUS_DROP;
+ const GstStructure *structure;
+ gint64 position, length;
+ GstFormat format = GST_FORMAT_TIME;
+ const GValue *x_value, *y_value;
+ gint x, i, y;
+ /* select msg */
+ if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT ||
+ !gst_structure_has_name (gst_message_get_structure (message),
+ "hand-gesture"))
+ return GST_BUS_PASS;
+
+ /* parse msg structure */
+ structure = gst_message_get_structure (message);
+
+ /* if PALM gesture detected */
+ if (structure &&
+ strcmp (gst_structure_get_name (structure), "hand-gesture") == 0 &&
+ strcmp (gst_structure_get_string (structure, "gesture"), "palm") == 0) {
+ /* media operation - closed palm to stop media play */
+ gst_element_set_state (playbin, GST_STATE_PAUSED);
+ }
+
+ /* if FIST gesture detected */
+ if (structure &&
+ strcmp (gst_structure_get_name (structure), "hand-gesture") == 0 &&
+ strcmp (gst_structure_get_string (structure, "gesture"), "fist") == 0) {
+ /* print message type and structure name */
+ g_print ("%s{{%s}}\n", gst_message_type_get_name (message->type),
+ gst_structure_get_name (structure));
+ /* print msg structure names&values */
+ for (i = 0; i < gst_structure_n_fields (structure); i++) {
+ const gchar *name = gst_structure_nth_field_name (structure, i);
+ GType type = gst_structure_get_field_type (structure, name);
+ const GValue *value = gst_structure_get_value (structure, name);
+ type == G_TYPE_STRING ?
+ g_print ("-%s[%s]{%s}\n", name, g_type_name (type),
+ g_value_get_string (value)) : g_print ("-%s[%s]{%d}\n", name,
+ g_type_name (type), g_value_get_uint (value));
+ }
+ g_print ("\n");
+
+ /* get X,Y positions in frame */
+ x_value = gst_structure_get_value (structure, "x");
+ x = g_value_get_uint (x_value);
+ y_value = gst_structure_get_value (structure, "y");
+ y = g_value_get_uint (y_value);
+
+ /* set object volumes [0-10] based on Y */
+ g_object_set (G_OBJECT (playbin), "volume", (gdouble) (10 - y / 24), NULL);
+
+ /* seek playback positions */
+ gst_element_query_duration (playbin, format, &length);
+ /* Width = 320 is specified in caps */
+ position = (gint64) length *x / 320;
+ gst_element_set_state (playbin, GST_STATE_PAUSED);
+ gst_element_seek (GST_ELEMENT (playbin),
+ 1.0,
+ format,
+ GST_SEEK_FLAG_FLUSH,
+ GST_SEEK_TYPE_SET, position, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
+ gst_element_set_state (GST_ELEMENT (playbin), GST_STATE_PLAYING);
+ }
+
+ gst_message_unref (message);
+ return GST_BUS_DROP;
}
-int main(gint argc, gchar **argv) {
- static GMainLoop *loop;
- loop = g_main_loop_new(NULL, FALSE);
- /* video source */
- gchar *video_device = "/dev/video0";
- gchar *video_file = "file:///home/javauser/workspace/gitfiles/gsthanddetect_app/video.avi";
- /* bus */
- GstBus *bus;
- /* caps */
- GstCaps *caps;
-
- /* init gst */
- gst_init(&argc, &argv);
-
- /* init elements */
- playbin = gst_element_factory_make("playbin2", "app_playbin");
- pipeline = gst_pipeline_new("app_pipeline");
- v4l2src = gst_element_factory_make("v4l2src", "app_v4l2src");
- videoscale = gst_element_factory_make("videoscale", "app_videoscale");
- ffmpegcolorspace_in = gst_element_factory_make("ffmpegcolorspace", "app_ffmpegcolorspace_in");
- handdetect = gst_element_factory_make("handdetect", "app_handdetect");
- ffmpegcolorspace_out = gst_element_factory_make("ffmpegcolorspace", "app_ffmpegcolorspace_out");
- xvimagesink = gst_element_factory_make("xvimagesink", "app_xvimagesink");
-
- /* check init results */
- if(!playbin || !pipeline || !v4l2src || !videoscale || !ffmpegcolorspace_in
- || !handdetect || !ffmpegcolorspace_out || !xvimagesink)
- g_error("ERROR: element init failed.\n");
-
- /* set values */
- g_object_set (G_OBJECT(playbin), "uri", video_file, NULL);
- g_object_set (G_OBJECT(v4l2src), "device", video_device, NULL);
- g_object_set (G_OBJECT (handdetect), "profile_fist", PROFILE_FIST, NULL);
- g_object_set (G_OBJECT (handdetect), "profile_palm", PROFILE_PALM, NULL);
-
- /* set caps */
- caps = gst_caps_from_string("video/x-raw-rgb, width=320, height=240, framerate=(fraction)30/1");
-
- /* set bus */
- bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
- gst_bus_set_sync_handler(bus, (GstBusSyncHandler) bus_sync_handler, pipeline);
- gst_object_unref(bus);
-
- /* add elements to pipeline */
- gst_bin_add_many(GST_BIN(pipeline),
- v4l2src,
- videoscale,
- ffmpegcolorspace_in,
- handdetect,
- ffmpegcolorspace_out,
- xvimagesink,
- NULL);
-
- /* negotiate caps */
- if(!gst_element_link_filtered( v4l2src, videoscale, caps)){
- g_printerr("ERROR:v4l2src -> videoscale caps\n");
- return 0; }
- gst_caps_unref(caps);
-
- /* link elements */
- gst_element_link_many(
- videoscale,
- ffmpegcolorspace_in,
- handdetect,
- ffmpegcolorspace_out,
- xvimagesink,
- NULL);
-
- /* change states */
- gst_element_set_state(pipeline, GST_STATE_PLAYING);
-
- /* start main loop */
- g_main_loop_run(loop);
-
- /* clean all */
- gst_element_set_state(pipeline, GST_STATE_NULL);
- gst_object_unref(GST_OBJECT(pipeline));
- gst_element_set_state(playbin, GST_STATE_NULL);
- gst_object_unref(GST_OBJECT(playbin));
-
- return 0;
+int
+main (gint argc, gchar ** argv)
+{
+ static GMainLoop *loop;
+ GstCaps *caps;
+ GstBus *bus;
+ gchar *uri;
+
+ const gchar *video_device = "/dev/video0";
+
+ if (argc < 2) {
+ fprintf (stderr, "oops, please give a file to play\n");
+ return -1;
+ }
+
+ uri = g_filename_to_uri (argv[1], NULL, NULL);
+ if (!uri) {
+ fprintf (stderr, "failed to create the uri\n");
+ return -1;
+ }
+
+ /* init gst */
+ gst_init (&argc, &argv);
+
+ loop = g_main_loop_new (NULL, FALSE);
+ /* init elements */
+ playbin = gst_element_factory_make ("playbin", "app_playbin");
+ pipeline = gst_pipeline_new ("app_pipeline");
+ v4l2src = gst_element_factory_make ("v4l2src", "app_v4l2src");
+ videoscale = gst_element_factory_make ("videoscale", "app_videoscale");
+ videoconvert_in =
+ gst_element_factory_make ("videoconvert", "app_videoconvert_in");
+ handdetect = gst_element_factory_make ("handdetect", "app_handdetect");
+ videoconvert_out =
+ gst_element_factory_make ("videoconvert", "app_videoconvert_out");
+ xvimagesink = gst_element_factory_make ("xvimagesink", "app_xvimagesink");
+
+ /* check init results */
+ if (!playbin || !pipeline || !v4l2src || !videoscale || !videoconvert_in
+ || !handdetect || !videoconvert_out || !xvimagesink)
+ g_error ("ERROR: element init failed.\n");
+
+ /* set values */
+ g_object_set (G_OBJECT (playbin), "uri", uri, NULL);
+ g_object_set (G_OBJECT (v4l2src), "device", video_device, NULL);
+
+ /* set caps */
+ caps =
+ gst_caps_from_string
+ ("video/x-raw, format=(string)RGB, width=320, height=240, framerate=(fraction)30/1");
+
+ /* set bus */
+ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+ gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bus_sync_handler, pipeline,
+ NULL);
+ gst_object_unref (bus);
+
+ /* add elements to pipeline */
+ gst_bin_add_many (GST_BIN (pipeline),
+ v4l2src,
+ videoscale,
+ videoconvert_in, handdetect, videoconvert_out, xvimagesink, NULL);
+
+ /* negotiate caps */
+ if (!gst_element_link_filtered (v4l2src, videoscale, caps)) {
+ g_printerr ("ERROR:v4l2src -> videoscale caps\n");
+ return 0;
+ }
+ gst_caps_unref (caps);
+
+ /* link elements */
+ gst_element_link_many (videoscale,
+ videoconvert_in, handdetect, videoconvert_out, xvimagesink, NULL);
+
+ /* change states */
+ gst_element_set_state (pipeline, GST_STATE_PLAYING);
+
+ /* start main loop */
+ g_main_loop_run (loop);
+
+ /* clean all */
+ gst_element_set_state (pipeline, GST_STATE_NULL);
+ gst_object_unref (GST_OBJECT (pipeline));
+ gst_element_set_state (playbin, GST_STATE_NULL);
+ gst_object_unref (GST_OBJECT (playbin));
+
+ return 0;
}