Skip to content
Snippets Groups Projects
Commit c61c6050 authored by Remi Koenig's avatar Remi Koenig
Browse files

Ajout d'un plugin gstreamer de segmentation par couleur

parent cb016c0b
No related branches found
No related tags found
No related merge requests found
Showing
with 1943 additions and 0 deletions
This diff is collapsed.
SUBDIRS = src
EXTRA_DIST = autogen.sh
This diff is collapsed.
#!/bin/sh
# you can either set the environment variables AUTOCONF, AUTOHEADER, AUTOMAKE,
# ACLOCAL, AUTOPOINT and/or LIBTOOLIZE to the right versions, or leave them
# unset and get the defaults
autoreconf --verbose --force --install --make || {
echo 'autogen.sh failed';
exit 1;
}
./configure || {
echo 'configure failed';
exit 1;
}
echo
echo "Now type 'make' to compile this module."
echo
dnl required version of autoconf
AC_PREREQ([2.53])
dnl fill in your package name and package version here
AC_INIT([colorseg],[0.0.1])
dnl required versions of gstreamer and plugins-base
GST_REQUIRED=0.10.16
GSTPB_REQUIRED=0.10.16
AC_CONFIG_SRCDIR([src])
AC_CONFIG_HEADERS([config.h])
dnl required version of automake
AM_INIT_AUTOMAKE([1.10])
dnl enable mainainer mode by default
AM_MAINTAINER_MODE([enable])
dnl check for tools (compiler etc.)
AC_PROG_CC
dnl required version of libtool
LT_PREREQ([2.2.6])
LT_INIT
dnl give error and exit if we don't have pkgconfig
AC_CHECK_PROG(HAVE_PKGCONFIG, pkg-config, [ ], [
AC_MSG_ERROR([You need to have pkg-config installed!])
])
dnl Check for the required version of GStreamer core (and gst-plugins-base)
dnl This will export GST_CFLAGS and GST_LIBS variables for use in Makefile.am
dnl
dnl If you need libraries from gst-plugins-base here, also add:
dnl for libgstaudio-0.10: gstreamer-audio-0.10 >= $GST_REQUIRED
dnl for libgstvideo-0.10: gstreamer-video-0.10 >= $GST_REQUIRED
dnl for libgsttag-0.10: gstreamer-tag-0.10 >= $GST_REQUIRED
dnl for libgstpbutils-0.10: gstreamer-pbutils-0.10 >= $GST_REQUIRED
dnl for libgstfft-0.10: gstreamer-fft-0.10 >= $GST_REQUIRED
dnl for libgstinterfaces-0.10: gstreamer-interfaces-0.10 >= $GST_REQUIRED
dnl for libgstrtp-0.10: gstreamer-rtp-0.10 >= $GST_REQUIRED
dnl for libgstrtsp-0.10: gstreamer-rtsp-0.10 >= $GST_REQUIRED
dnl etc.
PKG_CHECK_MODULES(GST, [
gstreamer-0.10 >= $GST_REQUIRED
gstreamer-base-0.10 >= $GST_REQUIRED
gstreamer-video-0.10 >= $GST_REQUIRED
gstreamer-controller-0.10 >= $GST_REQUIRED
], [
AC_SUBST(GST_CFLAGS)
AC_SUBST(GST_LIBS)
], [
AC_MSG_ERROR([
You need to install or upgrade the GStreamer development
packages on your system. On debian-based systems these are
libgstreamer0.10-dev and libgstreamer-plugins-base0.10-dev.
on RPM-based systems gstreamer0.10-devel, libgstreamer0.10-devel
or similar. The minimum version required is $GST_REQUIRED.
])
])
dnl check if compiler understands -Wall (if yes, add -Wall to GST_CFLAGS)
AC_MSG_CHECKING([to see if compiler understands -Wall])
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Wall"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ ], [ ])], [
GST_CFLAGS="$GST_CFLAGS -Wall"
AC_MSG_RESULT([yes])
], [
AC_MSG_RESULT([no])
])
dnl set the plugindir where plugins should be installed (for src/Makefile.am)
if test "x${prefix}" = "x$HOME"; then
plugindir="$HOME/.gstreamer-0.10/plugins"
else
plugindir="\$(libdir)/gstreamer-0.10"
fi
AC_SUBST(plugindir)
dnl set proper LDFLAGS for plugins
GST_PLUGIN_LDFLAGS='-module -avoid-version -export-symbols-regex [_]*\(gst_\|Gst\|GST_\).*'
AC_SUBST(GST_PLUGIN_LDFLAGS)
AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT
# Note: plugindir is set in configure
plugin_LTLIBRARIES = libcolorseg.la
# sources used to compile this plug-in
libcolorseg_la_SOURCES = gstcolorseg.c gstcolorseg.h colorseg.c colorseg.h threshold.h
# compiler and linker flags used to compile this plugin, set in configure.ac
libcolorseg_la_CFLAGS = $(GST_CFLAGS)
libcolorseg_la_LIBADD = $(GST_LIBS)
libcolorseg_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libcolorseg_la_LIBTOOLFLAGS = --tag=disable-static
# headers we need but don't want installed
#noinst_HEADERS = gstplugin.h
#include <stdio.h>
#include <stdlib.h>
//#define NDEBUG
#include <assert.h>
#include "colorseg.h"
#include "threshold.h"
#define min(a, b) ((a<b)?a:b)
#define max(a, b) ((a>b)?a:b)
static inline color_class get_color_class(unsigned char *pixel) {
// Segmentation super rapide
// [Y/U/V]Class sont définis dans threshold.h
return YClass[pixel[0]] & UClass[pixel[1]] & VClass[pixel[2]];
}
static inline color_class get_color_class_YUY2(unsigned char *data, unsigned int pixel_nb) {
unsigned int offset = pixel_nb / 2;
unsigned int add = pixel_nb % 2;
unsigned char Y=data[4*offset + 2*add], U=data[4*offset + 1], V=data[4*offset + 3];
return YClass[Y] & UClass[U] & VClass[V];
}
static inline void set_pixel_YUY2(unsigned char *data, unsigned int pixel_nb, unsigned char Y, unsigned char U, unsigned char V) {
unsigned int offset = pixel_nb / 2;
unsigned int add = pixel_nb % 2;
data[4*offset + 2*add] = Y, data[4*offset + 1] = U, data[4*offset + 3] = V;
}
static inline void get_color_from_class(unsigned char *Y, unsigned char *U, unsigned char *V, color_class class) {
switch (class) {
case 0:
*Y = 0; *U = *V = 128;
break;
case 1:
*Y = 76; *U = 85; *V = 255;
break;
case 2:
*Y = 30; *U = 255; *V = 107;
break;
case 4:
*Y = 152; *U = 42; *V = 202;
break;
case 8:
*Y = 226; *U = 1; *V = 149;
break;
default:
*Y = 255; *U = *V = 128;
break;
}
}
void draw_segmentation(unsigned char *data, unsigned int width, unsigned int height, unsigned char mode) {
unsigned int i, j;
unsigned char Y, U, V;
for (j=0;j<height;j++) {
for (i=0;i<width;i+=2) {
color_class class = get_color_class_YUY2(data+width*j*2, i);
get_color_from_class(&Y, &U, &V, class);
unsigned char *l = data + width*2*j + 2*i;
if (mode == 0 || (mode == 1 && class != 0)) {
l[0] = Y;
l[1] = U;
l[2] = Y;
l[3] = V;
} else if (mode == 2) {
l[0] = ((l[0]>>1) + (Y>>1));
l[1] = ((l[1]>>1) + (U>>1));
l[2] = ((l[2]>>1) + (Y>>1));
l[3] = ((l[3]>>1) + (V>>1));
}
}
}
}
#ifndef COLORSEG_INCLUDED
#define COLORSEG_INCLUDED
typedef enum {
COLOR_SEG_NORMAL,
COLOR_SEG_OVERLAY,
COLOR_SEG_MIX,
COLOR_SEG_NONE
} ColorSegMethod;
typedef unsigned char color_class;
void draw_segmentation(unsigned char *data, unsigned int width, unsigned int height, unsigned char mode);
#endif // COLORSEG_INCLUDED
/*
* GStreamer ColorSeg plugin
* Copyright (C) 2010 Rémi <<user@hostname.org>>
*
* 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.
*/
/**
* SECTION:element-colorseg
*
* FIXME:Describe colorseg here.
*
* <refsect2>
* <title>Example launch line</title>
* |[
* gst-launch -v -m fakesrc ! colorseg ! fakesink silent=TRUE
* ]|
* </refsect2>
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/video/video.h>
#include "colorseg.h"
#include "gstcolorseg.h"
/* debug variable definition */
GST_DEBUG_CATEGORY (gst_color_seg_debug);
/* Filter signals and args */
enum
{
/* FILL ME */
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_DRAW_MODE,
};
/* the capabilities of the inputs and outputs.
*/
static GstStaticPadTemplate sink_template =
GST_STATIC_PAD_TEMPLATE (
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-raw-yuv, "
"format = (fourcc) YUY2")
);
static GstStaticPadTemplate src_template =
GST_STATIC_PAD_TEMPLATE (
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-raw-yuv, "
"format = (fourcc) YUY2")
);
#define DEFAULT_PROP_DRAW_MODE COLOR_SEG_NORMAL
#define GST_TYPE_COLOR_SEG_METHOD (gst_color_seg_method_get_type())
static GType
gst_color_seg_method_get_type (void)
{
static GType color_seg_method_type = 0;
static const GEnumValue color_seg_methods[] = {
{COLOR_SEG_NORMAL, "Normal", "normal"},
{COLOR_SEG_OVERLAY, "Overlay", "overlay"},
{COLOR_SEG_MIX, "Mix", "mix"},
{0, NULL, NULL},
};
if (!color_seg_method_type) {
color_seg_method_type =
g_enum_register_static ("ColorSegMethod", color_seg_methods);
}
return color_seg_method_type;
}
GST_BOILERPLATE (GstColorSeg, gst_color_seg, GstVideoFilter,
GST_TYPE_VIDEO_FILTER);
static void gst_color_seg_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_color_seg_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstFlowReturn gst_color_seg_transform_ip (GstBaseTransform * base,
GstBuffer * outbuf);
static gboolean gst_color_seg_set_caps (GstBaseTransform * base, GstCaps * incaps, GstCaps * outcaps);
/* GObject vmethod implementations */
static void
gst_color_seg_base_init (gpointer klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_set_details_simple (element_class,
"ColorSeg",
"Filter/Effect/Video",
"Misc operations",
"Rémi Koenig <remi.koenig@telecom-bretagne.eu>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_template));
}
/* initialize the colorseg's class */
static void
gst_color_seg_class_init (GstColorSegClass * klass)
{
GObjectClass *gobject_class;
gobject_class = (GObjectClass *) klass;
gobject_class->set_property = gst_color_seg_set_property;
gobject_class->get_property = gst_color_seg_get_property;
g_object_class_install_property (gobject_class, PROP_DRAW_MODE,
g_param_spec_enum ("draw-mode", "Draw mode", "0, 1 or 2",
GST_TYPE_COLOR_SEG_METHOD, DEFAULT_PROP_DRAW_MODE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
GST_BASE_TRANSFORM_CLASS (klass)->transform_ip =
GST_DEBUG_FUNCPTR (gst_color_seg_transform_ip);
GST_BASE_TRANSFORM_CLASS (klass)->set_caps =
GST_DEBUG_FUNCPTR (gst_color_seg_set_caps);
}
/* initialize the new element
* initialize instance structure
*/
static void
gst_color_seg_init (GstColorSeg *filter, GstColorSegClass * klass)
{
filter->draw_mode = DEFAULT_PROP_DRAW_MODE;
}
static void
gst_color_seg_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstColorSeg *filter = GST_COLORSEG (object);
switch (prop_id) {
case PROP_DRAW_MODE:
filter->draw_mode = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_color_seg_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstColorSeg *filter = GST_COLORSEG (object);
switch (prop_id) {
case PROP_DRAW_MODE:
g_value_set_enum (value, filter->draw_mode);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static gboolean
gst_color_seg_set_caps (GstBaseTransform * base, GstCaps * incaps, GstCaps * outcaps)
{
GstColorSeg *filter = GST_COLORSEG (base);
gboolean ret = TRUE;
ret = gst_video_format_parse_caps (incaps, NULL,
&filter->width, &filter->height);
if (!ret)
return ret;
g_print ("Caps negotiation succeeded with %dx%d\n",
(gint)filter->width, (gint)filter->height);
return ret;
}
/* GstBaseTransform vmethod implementations */
/* this function does the actual processing
*/
static GstFlowReturn
gst_color_seg_transform_ip (GstBaseTransform * base, GstBuffer * outbuf)
{
GstColorSeg *filter = GST_COLORSEG (base);
draw_segmentation(outbuf->data, filter->width, filter->height, filter->draw_mode);
return GST_FLOW_OK;
}
/* entry point to initialize the plug-in
* initialize the plug-in itself
* register the element factories and other features
*/
static gboolean
colorseg_init (GstPlugin * colorseg)
{
if (!gst_element_register (colorseg, "colorseg", GST_RANK_NONE,
GST_TYPE_COLORSEG))
return FALSE;
GST_DEBUG_CATEGORY_INIT (gst_color_seg_debug, "colorseg", 0,
"colorseg element");
return TRUE;
}
/* gstreamer looks for this structure to register colorsegs
*/
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"colorseg",
"Color segmentation",
colorseg_init,
VERSION,
"LGPL",
"GStreamer",
"http://gstreamer.net/"
)
/*
* GStreamer ColorSeg plugin
* Copyright (C) 2010 Rémi <<user@hostname.org>>
*
* 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_COLORSEG_H__
#define __GST_COLORSEG_H__
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/video/gstvideofilter.h>
#include "colorseg.h"
G_BEGIN_DECLS
GST_DEBUG_CATEGORY_EXTERN (gst_color_seg_debug);
#define GST_CAT_DEFAULT gst_color_seg_debug
#define GST_TYPE_COLORSEG \
(gst_color_seg_get_type())
#define GST_COLORSEG(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_COLORSEG,GstColorSeg))
#define GST_COLORSEG_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_COLORSEG,GstColorSegClass))
#define GST_IS_COLORSEG(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_COLORSEG))
#define GST_IS_COLORSEG_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_COLORSEG))
typedef struct _GstColorSeg GstColorSeg;
typedef struct _GstColorSegClass GstColorSegClass;
struct _GstColorSeg {
GstVideoFilter element;
ColorSegMethod draw_mode;
unsigned int width, height;
};
struct _GstColorSegClass {
GstVideoFilterClass parent_class;
};
GType gst_color_seg_get_type (void);
G_END_DECLS
#endif /* __GST_COLORSEG_H__ */
#ifndef THRESHOLD_INCLUDED
#define THRESHOLD_INCLUDED
#include "colorseg.h"
color_class YClass[256] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
color_class UClass[256] = {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
color_class VClass[256] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
#endif // THRESHOLD_INCLUDED
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment