From 7f26eaf9c595d26ab12b138ea9495e88ba7a1d52 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Thu, 1 Oct 2009 23:51:04 +0300 Subject: [PATCH] zbar: wrap zbar library as a image analyzer zbar is a bar code scanner library. --- configure.ac | 9 ++ ext/zbar/Makefile.am | 11 ++ ext/zbar/gstzbar.c | 269 +++++++++++++++++++++++++++++++++++++++++++ ext/zbar/gstzbar.h | 71 ++++++++++++ 4 files changed, 360 insertions(+) create mode 100644 ext/zbar/Makefile.am create mode 100644 ext/zbar/gstzbar.c create mode 100644 ext/zbar/gstzbar.h diff --git a/configure.ac b/configure.ac index bfd3817ee4..32030c5e5a 100644 --- a/configure.ac +++ b/configure.ac @@ -299,6 +299,7 @@ AG_GST_CHECK_PLUGIN(valve) AG_GST_CHECK_PLUGIN(videomeasure) AG_GST_CHECK_PLUGIN(videosignal) AG_GST_CHECK_PLUGIN(vmnc) +AG_GST_CHECK_PLUGIN(zbar) dnl *** plug-ins to exclude *** @@ -1596,6 +1597,12 @@ AG_GST_CHECK_FEATURE(SCHRO, [Schroedinger video codec], schro, [ AG_GST_PKG_CHECK_MODULES(SCHRO, schroedinger-1.0 >= 1.0.7) ]) +dnl *** zbar *** +translit(dnm, m, l) AM_CONDITIONAL(USE_ZBAR, true) +AG_GST_CHECK_FEATURE(ZBAR, [ZBar barcode detector], zbar, [ + AG_GST_PKG_CHECK_MODULES(ZBAR, zbar >= 0.9) +]) + else dnl not building plugins with external dependencies, @@ -1655,6 +1662,7 @@ AM_CONDITIONAL(USE_WININET, false) AM_CONDITIONAL(USE_ACM, false) AM_CONDITIONAL(USE_VDPAU, false) AM_CONDITIONAL(USE_SCHRO, false) +AM_CONDITIONAL(USE_ZBAR, false) fi dnl of EXT plugins @@ -1855,6 +1863,7 @@ ext/swfdec/Makefile ext/theora/Makefile ext/timidity/Makefile ext/xvid/Makefile +ext/zbar/Makefile po/Makefile.in docs/Makefile docs/plugins/Makefile diff --git a/ext/zbar/Makefile.am b/ext/zbar/Makefile.am new file mode 100644 index 0000000000..2b1f370074 --- /dev/null +++ b/ext/zbar/Makefile.am @@ -0,0 +1,11 @@ +plugin_LTLIBRARIES = libgstzbar.la + +libgstzbar_la_SOURCES = gstzbar.c + +libgstzbar_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(ZBAR_CFLAGS) +libgstzbar_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstvideo-@GST_MAJORMINOR@ $(GST_BASE_LIBS) $(GST_LIBS) $(ZBAR_LIBS) +libgstzbar_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +libgstzbar_la_LIBTOOLFLAGS = --tag=disable-static + +noinst_HEADERS = gstzbar.h + diff --git a/ext/zbar/gstzbar.c b/ext/zbar/gstzbar.c new file mode 100644 index 0000000000..f77efa786a --- /dev/null +++ b/ext/zbar/gstzbar.c @@ -0,0 +1,269 @@ +/* GStreamer + * Copyright (C) 2009 Stefan Kost + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * This file was (probably) generated from + * gstvideotemplate.c,v 1.12 2004/01/07 21:07:12 ds Exp + * and + * make_filter,v 1.6 2004/01/07 21:33:01 ds Exp + */ + +/** + * SECTION:element-zbar + * + * Detect bar codes in the video streams and send them as app messages. + * + * + * Example launch lines + * |[ + * gst-launch -m v4l2src ! ffmpegcolorspace ! zbar ! ffmpegcolorspace ! xvimagesink + * ]| This pipeline will detect barcodes and send them as messages. + * |[ + * gst-launch -m v4l2src ! tee name=t ! queue ! ffmpegcolorspace ! zbar ! fakesink t. ! queue ! xvimagesink + * ]| Same as above, but running the filter on a branch to keep the display in color + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstzbar.h" + +#include +#include + +#include + + +GST_DEBUG_CATEGORY_STATIC (zbar_debug); +#define GST_CAT_DEFAULT zbar_debug + +/* GstZBar signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; + +enum +{ + PROP_0, + /* FILL ME */ +}; + +#define DEFAULT_PROP_ZBAR 1 + +static const GstElementDetails zbar_details = +GST_ELEMENT_DETAILS ("Barcode detector", + "Filter/Analyzer/Video", + "Detect bar codes in the video streams", + "Stefan Kost "); + +static GstStaticPadTemplate gst_zbar_src_template = +GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ Y800 }")) + ); + +static GstStaticPadTemplate gst_zbar_sink_template = +GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ Y800 }")) + ); + +static void gst_zbar_finalize (GObject * object); +static void gst_zbar_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_zbar_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +static gboolean gst_zbar_set_caps (GstBaseTransform * base, GstCaps * incaps, + GstCaps * outcaps); +static GstFlowReturn gst_zbar_transform_ip (GstBaseTransform * transform, + GstBuffer * buf); + +GST_BOILERPLATE (GstZBar, gst_zbar, GstVideoFilter, GST_TYPE_VIDEO_FILTER); + + +static void +gst_zbar_base_init (gpointer g_class) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + + gst_element_class_set_details (element_class, &zbar_details); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_zbar_sink_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_zbar_src_template)); +} + +static void +gst_zbar_class_init (GstZBarClass * g_class) +{ + GObjectClass *gobject_class; + GstBaseTransformClass *trans_class; + + gobject_class = G_OBJECT_CLASS (g_class); + trans_class = GST_BASE_TRANSFORM_CLASS (g_class); + + gobject_class->set_property = gst_zbar_set_property; + gobject_class->get_property = gst_zbar_get_property; + gobject_class->finalize = gst_zbar_finalize; + + trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_zbar_set_caps); + trans_class->transform_ip = GST_DEBUG_FUNCPTR (gst_zbar_transform_ip); +} + +static void +gst_zbar_init (GstZBar * zbar, GstZBarClass * g_class) +{ + zbar->scanner = zbar_image_scanner_create (); + /* FIXME: do this in start/stop vmethods */ + zbar_image_scanner_enable_cache (zbar->scanner, TRUE); +} + +static void +gst_zbar_finalize (GObject * object) +{ + GstZBar *zbar = GST_ZBAR (object); + + zbar_image_scanner_destroy (zbar->scanner); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gst_zbar_set_property (GObject * object, guint prop_id, const GValue * value, + GParamSpec * pspec) +{ + GstZBar *zbar; + + g_return_if_fail (GST_IS_ZBAR (object)); + zbar = GST_ZBAR (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_zbar_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstZBar *zbar; + + g_return_if_fail (GST_IS_ZBAR (object)); + zbar = GST_ZBAR (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +gst_zbar_set_caps (GstBaseTransform * base, GstCaps * incaps, GstCaps * outcaps) +{ + GstZBar *this; + GstStructure *structure; + gboolean res; + + this = GST_ZBAR (base); + + GST_DEBUG_OBJECT (this, + "set_caps: in %" GST_PTR_FORMAT " out %" GST_PTR_FORMAT, incaps, outcaps); + + structure = gst_caps_get_structure (incaps, 0); + + res = gst_structure_get_int (structure, "width", &this->width); + res &= gst_structure_get_int (structure, "height", &this->height); + if (!res) + goto done; + +done: + return res; +} + +static GstFlowReturn +gst_zbar_transform_ip (GstBaseTransform * base, GstBuffer * outbuf) +{ + GstZBar *zbar; + guint8 *data; + guint size; + zbar_image_t *image; + const zbar_symbol_t *symbol; + int n; + + zbar = GST_ZBAR (base); + + if (base->passthrough) + goto done; + + data = GST_BUFFER_DATA (outbuf); + size = GST_BUFFER_SIZE (outbuf); + + image = zbar_image_create (); + zbar_image_set_format (image, *(gint *) "Y800"); + zbar_image_set_size (image, zbar->width, zbar->height); + zbar_image_set_data (image, (gpointer) data, zbar->width * zbar->height, + NULL); + + + /* scan the image for barcodes */ + n = zbar_scan_image (zbar->scanner, image); + + /* extract results */ + symbol = zbar_image_first_symbol (image); + for (; symbol; symbol = zbar_symbol_next (symbol)) { + /* do something useful with results */ + zbar_symbol_type_t typ = zbar_symbol_get_type (symbol); + const char *data = zbar_symbol_get_data (symbol); + printf ("decoded %s symbol \"%s\"\n", zbar_get_symbol_name (typ), data); + } + + /* clean up */ + zbar_image_destroy (image); + + +done: + return GST_FLOW_OK; + +/* ERRORS */ +} + +static gboolean +plugin_init (GstPlugin * plugin) +{ + GST_DEBUG_CATEGORY_INIT (zbar_debug, "zbar", 0, "zbar"); + + return gst_element_register (plugin, "zbar", GST_RANK_NONE, GST_TYPE_ZBAR); +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "zbar", + "zbar barcode scanner", + plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN); diff --git a/ext/zbar/gstzbar.h b/ext/zbar/gstzbar.h new file mode 100644 index 0000000000..0948c4e92a --- /dev/null +++ b/ext/zbar/gstzbar.h @@ -0,0 +1,71 @@ +/* GStreamer + * Copyright (C) 2009 Stefan Kost + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#ifndef __GST_VIDEO_ZBAR_H__ +#define __GST_VIDEO_ZBAR_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_ZBAR \ + (gst_zbar_get_type()) +#define GST_ZBAR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ZBAR,GstZBar)) +#define GST_ZBAR_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ZBAR,GstZBarClass)) +#define GST_IS_ZBAR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ZBAR)) +#define GST_IS_ZBAR_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ZBAR)) + +typedef struct _GstZBar GstZBar; +typedef struct _GstZBarClass GstZBarClass; + +/** + * GstZBar: + * + * Opaque data structure. + */ +struct _GstZBar +{ + GstVideoFilter videofilter; + + /* format */ + gint width; + gint height; + + /* properties */ + + /* internals */ + zbar_image_scanner_t *scanner; +}; + +struct _GstZBarClass +{ + GstVideoFilterClass parent_class; +}; + +GType gst_zbar_get_type(void); + +G_END_DECLS + +#endif /* __GST_VIDEO_ZBAR_H__ */