gegl r2259 - in trunk: . operations/external operations/external/v4lutils



Author: ok
Date: Tue Apr 29 21:17:55 2008
New Revision: 2259
URL: http://svn.gnome.org/viewvc/gegl?rev=2259&view=rev

Log:
* operations/external/v4l.c: added v4l source operation from gggl.
* operations/external/v4lutils/: added v4lutils from effectv.
* operations/external/Makefile.am: updated.


Added:
   trunk/operations/external/v4l.c
   trunk/operations/external/v4lutils/
   trunk/operations/external/v4lutils/README
   trunk/operations/external/v4lutils/v4lutils.c
   trunk/operations/external/v4lutils/v4lutils.h
Modified:
   trunk/ChangeLog
   trunk/operations/external/Makefile.am

Modified: trunk/operations/external/Makefile.am
==============================================================================
--- trunk/operations/external/Makefile.am	(original)
+++ trunk/operations/external/Makefile.am	Tue Apr 29 21:17:55 2008
@@ -60,6 +60,14 @@
 display_la_CFLAGS = $(SDL_CFLAGS)
 endif
 
+#if HAVE_V4L
+ops += v4l.la
+v4l_la_SOURCES = v4l.c
+v4l_la_LIBADD = $(op_libs)
+#endif
+
+EXTRA_DIST=v4lutils/v4lutils.c v4lutils/v4lutils.h
+
 if HAVE_AVCODEC
 if HAVE_AVFORMAT
 ops += ff-load.la

Added: trunk/operations/external/v4l.c
==============================================================================
--- (empty file)
+++ trunk/operations/external/v4l.c	Tue Apr 29 21:17:55 2008
@@ -0,0 +1,294 @@
+/* Video4Linux operation for GEGL
+ *
+ * GEGL is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * GEGL 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright 2004-2008 Ãyvind KolÃs <pippin gimp org>
+ *                     originally written for gggl
+ */
+#ifdef GEGL_CHANT_PROPERTIES
+
+gegl_chant_path (path,   "Path", "/dev/video0", "Path to v4l device")
+gegl_chant_int  (width,  "Width", 0, G_MAXINT, 320, "Width for rendered image")
+gegl_chant_int  (height, "Height", 0, G_MAXINT, 240, "Height for rendered image")
+gegl_chant_int  (frame,  "Frame", 0, G_MAXINT, 0, "current frame number, can be changed to trigger a reload of the image.")
+
+#else
+
+#define GEGL_CHANT_TYPE_SOURCE
+#define GEGL_CHANT_C_FILE       "v4l.c"
+
+#include "gegl-chant.h"
+
+#include "v4lutils/v4lutils.h"
+#include "v4lutils/v4lutils.c"
+
+typedef struct
+{
+  gint active;
+  gint w;
+  gint h;
+  gint w_stored;
+  gint h_stored;
+  gint frame;
+  gint decode;
+  v4ldevice *vd;
+} Priv;
+
+static void
+init (GeglChantO *o)
+{
+  Priv *p = (Priv*)o->chant_data;
+
+  if (p==NULL)
+    {
+      p = g_new0 (Priv, 1);
+      o->chant_data = (void*) p;
+    }
+
+  p->w = 320;
+  p->h = 240;
+}
+
+
+static GeglRectangle
+get_bounding_box (GeglOperation *operation)
+{
+  GeglRectangle result ={0,0,320,200};
+  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
+
+  result.width = o->width;
+  result.height = o->height;
+  return result;
+}
+
+static void
+prepare (GeglOperation *operation)
+{
+  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
+  Priv *p= (Priv*)o->chant_data;
+
+  if (p == NULL)
+    init (o);
+  p = (Priv*)o->chant_data;
+
+  gegl_operation_set_format (operation, "output",
+                            babl_format_new (
+                                  babl_model ("R'G'B'"),
+                                  babl_type ("u8"),
+                                  babl_component ("B'"),
+                                  babl_component ("G'"),
+                                  babl_component ("R'"),
+                                  NULL));
+
+  p->w = o->width;
+  p->h = o->height;
+
+  if (!p->vd)
+    {
+      p->vd = g_malloc0 (sizeof (v4ldevice));
+
+      if (v4lopen (o->path, p->vd))
+        return;
+
+      p->active = 1;
+
+      if (v4lmmap (p->vd))
+        return;
+
+      v4lsetdefaultnorm (p->vd, VIDEO_MODE_PAL);
+      v4lgetcapability (p->vd);
+
+      if (!(p->vd->capability.type & VID_TYPE_CAPTURE)) {
+          g_warning (
+               "video_init: This device seems not to support video capturing.\n");
+         return;
+      }
+    }
+
+  if (p->w != p->w_stored || p->h != p->h_stored)
+    {
+
+      if (p->w > p->vd->capability.maxwidth
+          || p->h > p->vd->capability.maxheight)
+        {
+          p->w = p->vd->capability.maxwidth;
+          p->h = p->vd->capability.maxheight;
+          o->width = p->w;
+          o->height = p->h;
+          g_warning ( "capturing size is set to %dx%d.\n", p->w, p->h);
+        }
+      else if (p->w < p->vd->capability.minwidth
+               || p->h < p->vd->capability.minheight)
+        {
+          p->w = p->vd->capability.minwidth;
+          p->h = p->vd->capability.minheight;
+          o->width = p->w;
+          o->height = p->h;
+          g_warning ( "capturing size is set to %dx%d.\n", p->w, p->h);
+        }
+
+      p->w_stored = p->w;
+      p->h_stored = p->h;
+
+      /* FIXME: try other palettes as well, do some profiling on the spca
+       * based cameras to see what is the ideal format wrt performance
+       */
+
+      if (!v4lsetpalette (p->vd, VIDEO_PALETTE_RGB24))
+        {
+           p->decode=0;
+        }
+      else if (!v4lsetpalette (p->vd, VIDEO_PALETTE_YUV420P))
+        {
+           p->decode=1;
+        }
+      else
+        {
+          g_warning ( "oops,. no usable v4l format found\n");
+          return;
+        }
+      v4lgrabinit (p->vd, p->w, p->h);
+      v4lgrabf (p->vd);
+    }
+}
+
+static void
+finalize (GObject *object)
+{
+ GeglChantO *o = GEGL_CHANT_PROPERTIES (object);
+
+  if (o->chant_data)
+    {
+      Priv *p = (Priv*)o->chant_data;
+
+      if (p->vd)
+        {
+          v4lmunmap (p->vd);
+          v4lclose (p->vd);
+          g_free (p->vd);
+        }
+      g_free (o->chant_data);
+      o->chant_data = NULL;
+    }
+
+  G_OBJECT_CLASS (g_type_class_peek_parent (G_OBJECT_GET_CLASS (object)))->finalize (object);
+}
+
+static gboolean
+process (GeglOperation       *operation,
+         GeglBuffer          *output,
+         const GeglRectangle *result)
+{
+  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
+  Priv       *p = (Priv*)o->chant_data;
+  guchar     *capbuf;
+
+  if (!p->active)
+    return FALSE;
+
+  v4lgrabf (p->vd);
+  capbuf = v4lgetaddress (p->vd);
+  v4lsyncf (p->vd);
+
+  if (!capbuf)
+    {
+      g_warning ("no capbuf found");
+      return FALSE;
+    }
+
+  if (p->decode)
+    {
+      guchar foobuf[o->width*o->height*3];
+          /* XXX: foobuf is unneeded the conversions resets for every
+           * scanline and could thus have been done in a line by line
+           * manner an fed into the output buffer
+           */
+      gint y;
+      for (y = 0; y < p->h; y++)
+        {
+          gint       x;
+
+          guchar *dst = &foobuf[y*p->w*3];
+          guchar *ysrc = (guchar *) (capbuf + (y) * (p->w) * 1);
+          guchar *usrc = (guchar *) (capbuf + (p->w) * (p->h) + (y) / 2 * (p->w) / 2);
+          guchar *vsrc = (guchar *) (capbuf + (p->w) * (p->h) + ((p->w) * (p->h)) / 4 + (y) / 2 * (p->w) / 2);
+
+          for (x = 0; x < p->w; x++)
+            {
+
+              gint       R, G, B;
+
+#ifndef byteclamp
+#define byteclamp(j) do{if(j<0)j=0; else if(j>255)j=255;}while(0)
+#endif
+
+#define YUV82RGB8(Y,U,V,R,G,B)do{\
+                  R= ((Y<<15)                 + 37355*(V-128))>>15;\
+                  G= ((Y<<15) -12911* (U-128) - 19038*(V-128))>>15;\
+                  B= ((Y<<15) +66454* (U-128)                )>>15;\
+                  byteclamp(R);\
+                  byteclamp(G);\
+                  byteclamp(B);\
+              }while(0)
+
+      /* the format support for this code is not very good, but it
+       * works for the devices I have tested with, conversion even
+       * for chroma subsampled images is something we should let
+       * babl handle.
+       */
+              YUV82RGB8 (*ysrc, *usrc, *vsrc, R, G, B);
+              dst[0] = B;
+              dst[1] = G;
+              dst[2] = R;
+
+              dst += 3;
+              ysrc++;
+              if (x % 2)
+                {
+                  usrc++;
+                  vsrc++;
+                }
+            }
+        }
+      gegl_buffer_set (output, NULL, NULL, foobuf, GEGL_AUTO_ROWSTRIDE);
+    }
+  else
+    {
+      gegl_buffer_set (output, NULL, NULL, capbuf, GEGL_AUTO_ROWSTRIDE);
+    }
+  return  TRUE;
+}
+
+static void
+gegl_chant_class_init (GeglChantClass *klass)
+{
+  GeglOperationClass       *operation_class;
+  GeglOperationSourceClass *source_class;
+
+  G_OBJECT_CLASS (klass)->finalize = finalize;
+
+  operation_class = GEGL_OPERATION_CLASS (klass);
+  source_class    = GEGL_OPERATION_SOURCE_CLASS (klass);
+
+  source_class->process             = process;
+  operation_class->get_bounding_box = get_bounding_box;
+  operation_class->prepare          = prepare;
+
+  operation_class->name        = "v4l";
+  operation_class->categories  = "input:video";
+  operation_class->description = "Video4Linux input, webcams framegrabbers and similar devices.";
+}
+
+
+#endif

Added: trunk/operations/external/v4lutils/README
==============================================================================
--- (empty file)
+++ trunk/operations/external/v4lutils/README	Tue Apr 29 21:17:55 2008
@@ -0,0 +1,37 @@
+v4lutils - utility library for Video4Linux
+
+GENERAL INFORMATION
+===================
+V4lutils is a utility library wraps Video4Linux API.
+Currently, v4lutils is developled and released as a part of EffecTV, but you
+can use and/or release this library separated from EffecTV.
+
+SUMMARY OF USAGE
+================
+V4lutils employs OO-like model. All of status is stored in "v4ldevice" struct.
+Please read comments in v4lutils.c for the details.
+V4lutils is almost thread safe (I belive). v4lperror() may cause problem.
+I'll try to fix this problem ASAP.
+
+CONTACT
+=======
+Bug-reporting & Suggestions
+---------------------------
+Send an e-mail to:
+
+fukuchi users sourceforge net
+
+LICENSING INFORMATION
+=====================
+This library is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+AUTHOR
+======
+Kentaro Fukuchi <fukuchi users sourceforge net>

Added: trunk/operations/external/v4lutils/v4lutils.c
==============================================================================
--- (empty file)
+++ trunk/operations/external/v4lutils/v4lutils.c	Tue Apr 29 21:17:55 2008
@@ -0,0 +1,581 @@
+/*
+ * v4lutils - utility library for Video4Linux
+ * Copyright (C) 2001-2002 FUKUCHI Kentaro
+ *
+ * v4lutils.c: utility functions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <linux/videodev.h>
+#include <pthread.h>
+#include <errno.h>
+#include "v4lutils.h"
+
+#define DEFAULT_DEVICE "/dev/video"
+
+#define STRBUF_LENGTH 1024
+
+static int v4l_debug = 0; /* 1 = print debug message */
+
+static int v4lperror_level = V4L_PERROR_NONE;
+
+/*
+ * v4lperror - inhouse perror.
+ *
+ */
+static void v4lperror(const char *str)
+{
+	if(v4lperror_level >= V4L_PERROR_ALL)
+		perror(str);
+}
+
+/*
+ * v4lopen - open the v4l device.
+ *
+ * name: device file
+ * vd: v4l device object
+ */
+int v4lopen(char *name, v4ldevice *vd)
+{
+	int i;
+	char buf[STRBUF_LENGTH];
+
+	if(name == NULL)
+		name = DEFAULT_DEVICE;
+
+	if(v4l_debug) fprintf(stderr, "v4lopen:open...\n");
+	if((vd->fd = open(name,O_RDWR)) < 0) {
+		snprintf(buf, STRBUF_LENGTH, "v4lopen: failed to open %s", name);
+		v4lperror(buf);
+		return -1;
+	}
+	if(v4lgetcapability(vd))
+		return -1;
+
+	if(v4l_debug) fprintf(stderr, "v4lopen:VIDIOCGCHAN...\n");
+	for(i=0;i<vd->capability.channels;i++) {
+		vd->channel[i].channel = i;
+		if(ioctl(vd->fd, VIDIOCGCHAN, &(vd->channel[i])) < 0) {
+			v4lperror("v4lopen:VIDIOCGCHAN");
+			return -1;
+		}
+	}
+	v4lgetpicture(vd);
+	pthread_mutex_init(&vd->mutex, NULL);
+	if(v4l_debug) fprintf(stderr, "v4lopen:quit\n");
+	return 0;
+}
+
+/*
+ * v4lclose - close v4l device
+ *
+ * vd: v4l device object
+ */
+int v4lclose(v4ldevice *vd)
+{
+	if(v4l_debug) fprintf(stderr, "v4lclose:close...\n");
+	close(vd->fd);
+	if(v4l_debug) fprintf(stderr, "v4lclose:quit\n");
+	return 0;
+}
+
+/*
+ * v4lgetcapability - get the capability of v4l device
+ *
+ * vd: v4l device object
+ */
+int v4lgetcapability(v4ldevice *vd)
+{
+	if(v4l_debug) fprintf(stderr, "v4lgetcapability:VIDIOCGCAP...\n");
+	if(ioctl(vd->fd, VIDIOCGCAP, &(vd->capability)) < 0) {
+		v4lperror("v4lopen:VIDIOCGCAP");
+		return -1;
+	}
+	if(v4l_debug) fprintf(stderr, "v4lgetcapability:quit\n");
+	return 0;
+}
+
+/*
+ * v4lsetdefaultnorm - set default norm and reset parameters
+ *
+ * vd: v4l device object
+ * norm: default norm
+ */
+int v4lsetdefaultnorm(v4ldevice *vd, int norm)
+{
+	int i;
+
+	for(i=0;i<vd->capability.channels;i++) {
+		v4lsetchannelnorm(vd, i, norm);
+	}
+	if(v4lgetcapability(vd))
+		return -1;
+	if(v4lgetpicture(vd))
+		return -1;
+	return 0;
+}
+
+/*
+ * v4lgetsubcapture - get current status of subfield capturing
+ *
+ * vd: v4l device object
+ */
+int v4lgetsubcapture(v4ldevice *vd)
+{
+	if(ioctl(vd->fd, VIDIOCGCAPTURE, &(vd->capture)) < 0) {
+		v4lperror("v4lgetsubcapture:VIDIOCGCAPTURE");
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * v4lsetsubcapture - set parameters for subfield capturing
+ *
+ * vd: v4l device object
+ * x,y: coordinate of source rectangle to grab
+ * width: width of source rectangle to grab
+ * height: height of source rectangle to grab
+ * decimation: decimation to apply
+ * flags: flag setting for grabbing odd/even frames
+ */
+int v4lsetsubcapture(v4ldevice *vd, int x, int y, int width, int height, int decimation, int flags)
+{
+	vd->capture.x = x;
+	vd->capture.y = y;
+	vd->capture.width = width;
+	vd->capture.height = height;
+	vd->capture.decimation = decimation;
+	vd->capture.flags = flags;
+	if(ioctl(vd->fd, VIDIOCGCAPTURE, &(vd->capture)) < 0) {
+		v4lperror("v4lsetsubcapture:VIDIOCSCAPTURE");
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * v4lgetframebuffer - get current status of frame buffer
+ *
+ * vd: v4l device object
+ */
+int v4lgetframebuffer(v4ldevice *vd)
+{
+	if(ioctl(vd->fd, VIDIOCGFBUF, &(vd->buffer)) < 0) {
+		v4lperror("v4lgetframebuffer:VIDIOCGFBUF");
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * v4lsetframebuffer - set parameters of frame buffer
+ *
+ * vd: v4l device object
+ * base: base PHYSICAL address of the frame buffer
+ * width: width of the frame buffer
+ * height: height of the frame buffer
+ * depth: color depth of the frame buffer
+ * bpl: number of bytes of memory between the start of two adjacent lines
+ */
+int v4lsetframebuffer(v4ldevice *vd, void *base, int width, int height, int depth, int bpl)
+{
+	vd->buffer.base = base;
+	vd->buffer.width = width;
+	vd->buffer.height = height;
+	vd->buffer.depth = depth;
+	vd->buffer.bytesperline = bpl;
+	if(ioctl(vd->fd, VIDIOCSFBUF, &(vd->buffer)) < 0) {
+		v4lperror("v4lsetframebuffer:VIDIOCSFBUF");
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * v4loverlaystart - activate overlay capturing
+ *
+ * vd: v4l device object
+ */
+int v4loverlaystart(v4ldevice *vd)
+{
+	if(ioctl(vd->fd, VIDIOCCAPTURE, 1) < 0) {
+		v4lperror("v4loverlaystart:VIDIOCCAPTURE");
+		return -1;
+	}
+	vd->overlay = 1;
+	return 0;
+}
+
+/*
+ * v4loverlaystop - stop overlay capturing
+ *
+ * vd: v4l device object
+ */
+int v4loverlaystop(v4ldevice *vd)
+{
+	if(ioctl(vd->fd, VIDIOCCAPTURE, 0) < 0) {
+		v4lperror("v4loverlaystop:VIDIOCCAPTURE");
+		return -1;
+	}
+	vd->overlay = 0;
+	return 0;
+}
+
+/*
+ * v4lsetchannel - select the video source
+ *
+ * vd: v4l device object
+ * ch: the channel number
+ */
+int v4lsetchannel(v4ldevice *vd, int ch)
+{
+	if(ioctl(vd->fd, VIDIOCSCHAN, &(vd->channel[ch])) < 0) {
+		v4lperror("v4lsetchannel:VIDIOCSCHAN");
+		return -1;
+	}
+	return 0;
+}
+
+int v4lmaxchannel(v4ldevice *vd)
+{
+	return vd->capability.channels;
+}
+
+/*
+ * v4lsetfreq - set the frequency of tuner
+ *
+ * vd: v4l device object
+ * ch: frequency in KHz
+ */
+int v4lsetfreq(v4ldevice *vd, int freq)
+{
+	unsigned long longfreq=(freq*16)/1000;
+	if(ioctl(vd->fd, VIDIOCSFREQ, &longfreq) < 0) {
+		v4lperror("v4lsetfreq:VIDIOCSFREQ");
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * v4lsetchannelnorm - set the norm of channel
+ *
+ * vd: v4l device object
+ * ch: the channel number
+ * norm: PAL/NTSC/OTHER (see videodev.h)
+ */
+int v4lsetchannelnorm(v4ldevice *vd, int ch, int norm)
+{
+	vd->channel[ch].norm = norm;
+	return 0;
+}
+
+/*
+ * v4lgetpicture - get current properties of the picture
+ *
+ * vd: v4l device object
+ */
+int v4lgetpicture(v4ldevice *vd)
+{
+	if(ioctl(vd->fd, VIDIOCGPICT, &(vd->picture)) < 0) {
+		v4lperror("v4lgetpicture:VIDIOCGPICT");
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * v4lsetpicture - set the image properties of the picture
+ *
+ * vd: v4l device object
+ * br: picture brightness
+ * hue: picture hue
+ * col: picture color
+ * cont: picture contrast
+ * white: picture whiteness
+ */
+int v4lsetpicture(v4ldevice *vd, int br, int hue, int col, int cont, int white)
+{
+	if(br>=0)
+		vd->picture.brightness = br;
+	if(hue>=0)
+		vd->picture.hue = hue;
+	if(col>=0)
+		vd->picture.colour = col;
+	if(cont>=0)
+		vd->picture.contrast = cont;
+	if(white>=0)
+		vd->picture.whiteness = white;
+	if(ioctl(vd->fd, VIDIOCSPICT, &(vd->picture)) < 0) {
+		v4lperror("v4lsetpicture:VIDIOCSPICT");
+		return -1;
+	}
+	return 0;
+}
+ 
+/*
+ * v4lsetpalette - set the palette for the images
+ *
+ * vd: v4l device object
+ * palette: palette
+ */
+int v4lsetpalette(v4ldevice *vd, int palette)
+{
+	vd->picture.palette = palette;
+	vd->mmap.format = palette;
+	if(ioctl(vd->fd, VIDIOCSPICT, &(vd->picture)) < 0) {
+		v4lperror("v4lsetpalette:VIDIOCSPICT");
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * v4lgetmbuf - get the size of the buffer to mmap
+ *
+ * vd: v4l device object
+ */
+int v4lgetmbuf(v4ldevice *vd)
+{
+	if(ioctl(vd->fd, VIDIOCGMBUF, &(vd->mbuf))<0) {
+		v4lperror("v4lgetmbuf:VIDIOCGMBUF");
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * v4lmmap - initialize mmap interface
+ *
+ * vd: v4l device object
+ */
+int v4lmmap(v4ldevice *vd)
+{
+	if(v4lgetmbuf(vd)<0)
+		return -1;
+	if((vd->map = mmap(0, vd->mbuf.size, PROT_READ|PROT_WRITE, MAP_SHARED, vd->fd, 0)) < 0) {
+		v4lperror("v4lmmap:mmap");
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * v4lmunmap - free memory area for mmap interface
+ *
+ * vd: v4l device object
+ */
+int v4lmunmap(v4ldevice *vd)
+{
+	if(munmap(vd->map, vd->mbuf.size) < 0) {
+		v4lperror("v4lmunmap:munmap");
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * v4lgrabinit - set parameters for mmap interface
+ *
+ * vd: v4l device object
+ * width: width of the buffer
+ * height: height of the buffer
+ */
+int v4lgrabinit(v4ldevice *vd, int width, int height)
+{
+	vd->mmap.width = width;
+	vd->mmap.height = height;
+	vd->mmap.format = vd->picture.palette;
+	vd->frame = 0;
+	vd->framestat[0] = 0;
+	vd->framestat[1] = 0;
+	return 0;
+}
+
+/*
+ * v4lgrabstart - activate mmap capturing
+ *
+ * vd: v4l device object
+ * frame: frame number for storing captured image
+ */
+int v4lgrabstart(v4ldevice *vd, int frame)
+{
+	if(v4l_debug) fprintf(stderr, "v4lgrabstart: grab frame %d.\n",frame);
+	if(vd->framestat[frame]) {
+		fprintf(stderr, "v4lgrabstart: frame %d is already used to grab.\n", frame);
+	}
+	vd->mmap.frame = frame;
+	if(ioctl(vd->fd, VIDIOCMCAPTURE, &(vd->mmap)) < 0) {
+		v4lperror("v4lgrabstart:VIDIOCMCAPTURE");
+		return -1;
+	}
+	vd->framestat[frame] = 1;
+	return 0;
+}
+
+/*
+ * v4lsync - wait until mmap capturing of the frame is finished
+ *
+ * vd: v4l device object
+ * frame: frame number
+ */
+int v4lsync(v4ldevice *vd, int frame)
+{
+	if(v4l_debug) fprintf(stderr, "v4lsync: sync frame %d.\n",frame);
+	if(vd->framestat[frame] == 0) {
+		fprintf(stderr, "v4lsync: grabbing to frame %d is not started.\n", frame);
+	}
+	if(ioctl(vd->fd, VIDIOCSYNC, &frame) < 0) {
+		v4lperror("v4lsync:VIDIOCSYNC");
+		return -1;
+	}
+	vd->framestat[frame] = 0;
+	return 0;
+}
+
+/*
+ * v4llock - lock the Video4Linux device object
+ *
+ * vd: v4l device object
+ */
+int v4llock(v4ldevice *vd)
+{
+	return pthread_mutex_lock(&vd->mutex);
+}
+
+/*
+ * v4lunlock - unlock the Video4Linux device object
+ *
+ * vd: v4l device object
+ */
+int v4lunlock(v4ldevice *vd)
+{
+	return pthread_mutex_unlock(&vd->mutex);
+}
+
+/*
+ * v4ltrylock - lock the Video4Linux device object (non-blocking mode)
+ *
+ * vd: v4l device object
+ */
+int v4ltrylock(v4ldevice *vd)
+{
+	return pthread_mutex_trylock(&vd->mutex);
+}
+
+/*
+ * v4lsyncf - flip-flop sync
+ *
+ * vd: v4l device object
+ */
+int v4lsyncf(v4ldevice *vd)
+{
+	return v4lsync(vd, vd->frame);
+}
+
+/*
+ * v4lgrabf - flip-flop grabbing
+ *
+ * vd: v4l device object
+ */
+int v4lgrabf(v4ldevice *vd)
+{
+	int f;
+
+	f = vd->frame;
+	vd->frame = vd->frame ^ 1;
+	return v4lgrabstart(vd, f);
+}
+
+/*
+ * v4lgetaddress - returns a offset addres of buffer for mmap capturing
+ *
+ * vd: v4l device object
+ */
+unsigned char *v4lgetaddress(v4ldevice *vd)
+{
+	return (vd->map + vd->mbuf.offsets[vd->frame]);
+}
+
+/*
+ * v4lreadframe - grab one frame by calling read system call
+ * vd: v4l device object
+ * buf: buffer where a grabbed imaged is stored
+ */
+
+int v4lreadframe(v4ldevice *vd, unsigned char *buf)
+{
+	/* to do */
+	return -1;
+}
+
+/*
+ * v4lprint - print v4l device object
+ *
+ * vd: v4l device object
+ */
+void v4lprint(v4ldevice *vd)
+{
+	printf("v4l device data\nname: %s\n",vd->capability.name);
+	printf("channels: %d\n",vd->capability.channels);
+	printf("max size: %dx%d\n",vd->capability.maxwidth, vd->capability.maxheight);
+	printf("min size: %dx%d\n",vd->capability.minwidth, vd->capability.minheight);
+	printf("device type;\n");
+	if(vd->capability.type & VID_TYPE_CAPTURE) printf("VID_TYPE_CAPTURE,");
+	if(vd->capability.type & VID_TYPE_OVERLAY) printf("VID_TYPE_OVERLAY,");
+	if(vd->capability.type & VID_TYPE_CLIPPING) printf("VID_TYPE_CLIPPING,");
+	if(vd->capability.type & VID_TYPE_FRAMERAM) printf("VID_TYPE_FRAMERAM,");
+	if(vd->capability.type & VID_TYPE_SCALES) printf("VID_TYPE_SCALES,");
+	if(vd->capability.type & VID_TYPE_MONOCHROME) printf("VID_TYPE_MONOCHROME,");
+	if(vd->capability.type & VID_TYPE_SUBCAPTURE) printf("VID_TYPE_SUBCAPTURE,");
+	printf("\ncurrent status;\n");
+	printf("picture.depth: %d\n",vd->picture.depth);
+	printf("mbuf.size: %08x\n",vd->mbuf.size);
+	printf("mbuf.frames: %d\n",vd->mbuf.frames);
+	printf("mbuf.offsets[0]: %08x\n",vd->mbuf.offsets[0]);
+	printf("mbuf.offsets[1]: %08x\n",vd->mbuf.offsets[1]);
+}
+
+/*
+ * v4lseterrorlevel - enable/disable perror message output
+ *
+ * flag: V4L_PERROR_NONE or V4L_PERROR_ALL(default)
+ */
+void v4lseterrorlevel(int flag)
+{
+	v4lperror_level = flag;
+}
+
+/*
+ * v4ldebug - enable/disable debug message output
+ *
+ * flag: 0 = disable / 1 = enable
+ */
+void v4ldebug(int flag)
+{
+	fprintf(stderr, "debug: %d\n",flag);
+	v4l_debug = flag;
+}

Added: trunk/operations/external/v4lutils/v4lutils.h
==============================================================================
--- (empty file)
+++ trunk/operations/external/v4lutils/v4lutils.h	Tue Apr 29 21:17:55 2008
@@ -0,0 +1,96 @@
+/*
+ * v4lutils - utility library for Video4Linux
+ * Copyright (C) 2001-2002 FUKUCHI Kentaro
+ *
+ * v4lutils.h: header file
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 __V4LUTILS_H__
+#define __V4LUTILS_H__
+
+#include <sys/types.h>
+#include <linux/videodev.h>
+#include <pthread.h>
+
+/*
+ * Error message displaying level
+ */
+#define V4L_PERROR_NONE (0)
+#define V4L_PERROR_ALL (1)
+
+/*
+ * Video4Linux Device Structure
+ */
+struct _v4ldevice
+{
+	int fd;
+	struct video_capability capability;
+	struct video_channel channel[10];
+	struct video_picture picture;
+	struct video_clip clip;
+	struct video_window window;
+	struct video_capture capture;
+	struct video_buffer buffer;
+	struct video_mmap mmap;
+	struct video_mbuf mbuf;
+	struct video_unit unit;
+	unsigned char *map;
+	pthread_mutex_t mutex;
+	int frame;
+	int framestat[2];
+	int overlay;
+};
+
+typedef struct _v4ldevice v4ldevice;
+
+extern int v4lopen(char *, v4ldevice *);
+extern int v4lclose(v4ldevice *);
+extern int v4lgetcapability(v4ldevice *);
+extern int v4lsetdefaultnorm(v4ldevice *, int);
+extern int v4lgetsubcapture(v4ldevice *);
+extern int v4lsetsubcapture(v4ldevice *, int, int, int, int, int, int);
+extern int v4lgetframebuffer(v4ldevice *);
+extern int v4lsetframebuffer(v4ldevice *, void *, int, int, int, int);
+extern int v4loverlaystart(v4ldevice *);
+extern int v4loverlaystop(v4ldevice *);
+extern int v4lsetchannel(v4ldevice *, int);
+extern int v4lmaxchannel(v4ldevice *);
+extern int v4lsetfreq(v4ldevice *,int);
+extern int v4lsetchannelnorm(v4ldevice *vd, int, int);
+extern int v4lgetpicture(v4ldevice *);
+extern int v4lsetpicture(v4ldevice *, int, int, int, int, int);
+extern int v4lsetpalette(v4ldevice *, int);
+extern int v4lgetmbuf(v4ldevice *);
+extern int v4lmmap(v4ldevice *);
+extern int v4lmunmap(v4ldevice *);
+extern int v4lgrabinit(v4ldevice *, int, int);
+extern int v4lgrabstart(v4ldevice *, int);
+extern int v4lsync(v4ldevice *, int);
+extern int v4llock(v4ldevice *);
+extern int v4ltrylock(v4ldevice *);
+extern int v4lunlock(v4ldevice *);
+extern int v4lsyncf(v4ldevice *);
+extern int v4lgrabf(v4ldevice *);
+extern unsigned char *v4lgetaddress(v4ldevice *);
+extern int v4lreadframe(v4ldevice *, unsigned char *);
+extern void v4lprint(v4ldevice *);
+extern void v4lseterrorlevel(int);
+extern void v4ldebug(int);
+
+#endif /* __V4LUTILS_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]