Sophie

Sophie

distrib > Mandriva > current > i586 > by-pkgid > 7b27fde6ab32bf68638c44d776e514b9 > files > 4

freej-0.10-2mdv2009.0.src.rpm

--- freej-0.9/src/include/impl_layers.h.v4l2	2007-09-01 20:21:17.000000000 +0200
+++ freej-0.9/src/include/impl_layers.h	2007-10-25 14:08:28.000000000 +0200
@@ -38,6 +38,7 @@
 
 #ifdef WITH_V4L
 #include <v4l_layer.h>
+#include <v4l2_layer.h>
 #endif
 
 #ifdef WITH_AVIFILE
--- freej-0.9/src/include/jsparser_data.h.v4l2	2007-09-01 20:21:17.000000000 +0200
+++ freej-0.9/src/include/jsparser_data.h	2007-10-25 14:08:28.000000000 +0200
@@ -60,6 +60,7 @@ JS(goom_layer_constructor);
 
 #ifdef WITH_V4L
 JS(v4l_layer_constructor);
+JS(v4l2_layer_constructor);
 #endif
 #ifdef WITH_AVCODEC
 JS(video_layer_constructor);
@@ -142,7 +143,9 @@ extern JSFunctionSpec goom_layer_methods
 // CamLayer
 #ifdef WITH_V4L
 extern JSClass v4l_layer_class;
+extern JSClass v4l2_layer_class;
 extern JSFunctionSpec v4l_layer_methods[];
+extern JSFunctionSpec v4l2_layer_methods[];
 #endif
 
 // TextLayer
@@ -332,6 +335,9 @@ JS(goom_layer_noise);
 JS(v4l_layer_chan);
 JS(v4l_layer_band);
 JS(v4l_layer_freq);
+JS(v4l2_layer_chan);
+JS(v4l2_layer_band);
+JS(v4l2_layer_freq);
 #endif
 
 #ifdef WITH_AVCODEC
--- freej-0.9/src/include/v4l2_layer.h.v4l2	2007-10-25 14:08:28.000000000 +0200
+++ freej-0.9/src/include/v4l2_layer.h	2007-10-25 14:16:56.000000000 +0200
@@ -0,0 +1,91 @@
+/*  FreeJ
+ *  (c) Copyright 2001 Denis Roio aka jaromil <jaromil@dyne.org>
+ *                     2007 Arnaud Patard <apatard@mandriva.com>
+ *
+ * This source code is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * This source code 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.
+ * Please refer to the GNU Public License for more details.
+ *
+ * You should have received a copy of the GNU Public License along with
+ * this source code; if not, write to:
+ * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __v4l2_h__
+#define __v4l2_h__
+
+/* this to avoid g++ complaining about videodev.h */
+typedef unsigned long int ulong;
+
+
+#include <linux/types.h>
+#include <linux/videodev.h>
+#include <context.h>
+
+
+#define BUF_COUNT	32
+
+struct buffer {
+	void *                  start;
+	size_t                  length;
+};
+
+class V4l2Grabber: public Layer {
+ private:
+  int dev;
+  int input;
+  int norm;
+  int _band;
+  int _freq;
+  uint32_t palette;
+
+  struct v4l2_capability grab_cap;
+  struct v4l2_format fmt;
+
+  struct v4l2_buffer buf;
+  struct v4l2_requestbuffers reqbuf;
+  struct buffer buffers[BUF_COUNT];
+
+  struct video_channel grab_chan;
+  struct video_picture grab_pic;
+  struct video_tuner grab_tuner;
+
+  bool grab24;
+  bool have_tuner;
+  //int minw, minh, maxw, maxh;
+  int channels;
+
+  void *get_buffer();
+
+  /* yuv2rgb conversion routine pointer
+     this is returned by yuv2rgb_init */
+  //  yuv2rgb_fun *yuv2rgb;
+  void *rgb_surface;
+  //  int u,v;  uv offset */
+
+  void print_err(char *ioctl, int res);
+ public:
+  V4l2Grabber();
+  ~V4l2Grabber();
+  bool open(char *devfile);
+  bool init(Context *freej);
+  bool init(Context *freej, int width, int height);
+  int width, height;
+  void *feed();
+  void close();
+
+  void set_chan(int ch);
+  void set_band(int b);
+  void set_freq(int f);
+  bool keypress(int key);
+
+  unsigned char *buffer;
+};
+
+#endif
--- freej-0.9/src/impl_layers.cpp.v4l2	2007-09-01 20:21:16.000000000 +0200
+++ freej-0.9/src/impl_layers.cpp	2007-10-25 14:08:28.000000000 +0200
@@ -95,19 +95,36 @@ Layer *create_layer(Context *env, char *
         end_file_ptr = file_ptr; 
       }
     }
-    nlayer = new V4lGrabber();
-    if(! ((V4lGrabber*)nlayer)->init( env, (int)w, (int)h) ) {
-      error("failed initialization of layer %s for %s", nlayer->name, file_ptr);
-      delete nlayer; return NULL;
+    nlayer = new V4l2Grabber();
+    if(! ((V4l2Grabber*)nlayer)->init( env, (int)w, (int)h) ) {
+    	error("failed initialization of layer %s for %s", nlayer->name, file_ptr);
+	delete nlayer; return NULL;
     }
     if(nlayer->open(file_ptr)) {
-        notice("v4l opened");
+        notice("v4l2 opened");
     //  ((V4lGrabber*)nlayer)->init_width = w;
     //  ((V4lGrabber*)nlayer)->init_heigth = h;
     } else {
-      error("create_layer : V4L open failed");
+      error("create_layer : V4L2 open failed");
       delete nlayer; nlayer = NULL;
     }
+
+    if (nlayer == NULL) {
+	nlayer = new V4lGrabber();
+	if(! ((V4lGrabber*)nlayer)->init( env, (int)w, (int)h) ) {
+      		error("failed initialization of layer %s for %s", nlayer->name, file_ptr);
+		delete nlayer; return NULL;
+	}
+    	if(nlayer->open(file_ptr)) {
+        	notice("v4l opened");
+	    //  ((V4lGrabber*)nlayer)->init_width = w;
+	    //  ((V4lGrabber*)nlayer)->init_heigth = h;
+	    } else {
+	      error("create_layer : V4L open failed");
+	      delete nlayer; nlayer = NULL;
+	    }
+    }
+
 #else
     error("Video4Linux layer support not compiled");
     act("can't load %s",file_ptr);
--- freej-0.9/src/Makefile.am.v4l2	2007-09-01 20:21:16.000000000 +0200
+++ freej-0.9/src/Makefile.am	2007-10-25 14:08:28.000000000 +0200
@@ -48,6 +48,8 @@ freej_SOURCES = \
 \
 	v4l_layer.cpp tvfreq.c	\
 	v4l_layer_js.cpp \
+	v4l2_layer.cpp \
+	v4l2_layer_js.cpp \
 	video_layer.cpp	\
 	video_layer_js.cpp \
 	image_layer.cpp \
--- freej-0.9/src/v4l2_layer.cpp.v4l2	2007-10-25 14:08:28.000000000 +0200
+++ freej-0.9/src/v4l2_layer.cpp	2007-10-25 14:17:03.000000000 +0200
@@ -0,0 +1,407 @@
+/*
+ *  V4L2 support for Freej
+ *  (c) Copyright 2001-2002 Denis Rojo aka jaromil <jaromil@dyne.org>
+ *                     2007 Arnaud Patard <apatard@mandriva.com>
+ *
+ * This source code is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * This source code 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.
+ * Please refer to the GNU Public License for more details.
+ *
+ * You should have received a copy of the GNU Public License along with
+ * this source code; if not, write to:
+ * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <config.h>
+
+#ifdef WITH_V4L
+
+#include <iostream>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <ccvt.h>
+#include <v4l2_layer.h>
+#include <tvfreq.h>
+#include <jutils.h>
+
+#include <jsparser_data.h>
+
+static inline __u32 try_video_palette(int dev, struct v4l2_format *fmt, __u32 pal)
+{
+  int res;
+  __u32 palette;
+
+  fmt->fmt.pix.pixelformat = pal;
+  res = ioctl(dev, VIDIOC_S_FMT, fmt);
+  if (res < 0) {
+    act("v4l2: palette %u not supported for grabbing, res: %i(%d) got instead: %u", pal, res, errno, fmt->fmt.pix.pixelformat);
+    palette = 0;
+  }
+  else {
+    act("v4l2: palette ok: %u", pal);
+    palette = fmt->fmt.pix.pixelformat;
+  }
+  return palette;
+}
+
+V4l2Grabber::V4l2Grabber() : Layer() {
+  dev = -1;
+  rgb_surface = NULL;
+  buffer = NULL;
+  have_tuner=false;
+  width = 320;
+  height = 240;
+  set_name("V4L2");
+  jsclass = &v4l2_layer_class;
+}
+
+V4l2Grabber::~V4l2Grabber() {
+  func("%s %s", __FILE__, __FUNCTION__);
+  close();
+}
+
+void V4l2Grabber::print_err(char *ioctl, int res) {
+       error("error in ioctl %s: (%i)", ioctl, res);
+       error("ERR %d %s dev: %i", errno, strerror(errno), dev);
+}
+
+void V4l2Grabber::close() {
+  int i, res, type;
+
+  func("%s %s", __FILE__, __FUNCTION__);
+
+  if (dev > 0) {
+     notice("Closing video4linux grabber layer");
+
+     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+     res = ioctl(dev, VIDIOC_STREAMOFF, &type);
+     if (res < 0) {
+       print_err("VIDIOC_STREAMOFF", res);
+     }
+  }
+
+  for (i = 0; i < BUF_COUNT; i++)
+	  munmap (buffers[i].start, buffers[i].length);
+
+  if(dev>0) {
+    act("closing video4linux device %u",dev);
+    ::close(dev);
+  }
+
+  if(rgb_surface) jfree(rgb_surface);
+
+}
+
+bool V4l2Grabber::open(char *file) {
+  int counter, res, type;
+  char *capabilities[] = {
+    "VID_TYPE_CAPTURE          can capture to memory",
+    "VID_TYPE_TUNER            has a tuner of some form",
+    "VID_TYPE_TELETEXT         has teletext capability",
+    "VID_TYPE_OVERLAY          can overlay its image to video",
+    "VID_TYPE_CHROMAKEY        overlay is chromakeyed",
+    "VID_TYPE_CLIPPING         overlay clipping supported",
+    "VID_TYPE_FRAMERAM         overlay overwrites video memory",
+    "VID_TYPE_SCALES           supports image scaling",
+    "VID_TYPE_MONOCHROME       image capture is grey scale only",
+    "VID_TYPE_SUBCAPTURE       capture can be of only part of the image"
+  };
+  __u32 formats[] = { V4L2_PIX_FMT_RGB32, V4L2_PIX_FMT_RGB32, V4L2_PIX_FMT_YUV422P,
+                      V4L2_PIX_FMT_YVU420, V4L2_PIX_FMT_YUYV
+                    };
+
+  func("%s %s detect()", __FILE__, __FUNCTION__);
+
+  if (-1 == (dev = ::open(file,O_RDWR|O_NONBLOCK))) {
+    error("open capture device %s: %s", file, strerror(errno));
+    return false;
+  } else {
+    ::close(dev);
+    dev = ::open(file,O_RDWR);
+  }
+
+  res = ioctl(dev, VIDIOC_QUERYCAP, &grab_cap);
+  if(res < 0) {
+    print_err("VIDIOC_QUERYCAP", res);
+    return false;
+  }
+
+  if(get_debug() > 0) {
+    notice("Device detected is %s", file);
+    act("%s", grab_cap.card);
+    act("Video capabilities:%x", grab_cap.capabilities);
+  }
+
+  if(grab_cap.capabilities & V4L2_CAP_TUNER)
+    /* if the device does'nt has any tuner, so we avoid some ioctl
+       this should be a fix for many webcams, thanks to Ben Wilson */
+    have_tuner = 1;
+
+  if(!(grab_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
+	  error("No V4L2_CAP_VIDEO_CAPTURE capability\n");
+	  return false;
+  }
+
+  if(!(grab_cap.capabilities & V4L2_CAP_STREAMING)) {
+	  error("No V4L2_CAP_STREAMING)) capability\n");
+	  return false;
+  }
+
+  memset(&fmt, 0, sizeof(struct v4l2_format));
+  fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  if (-1 == ioctl(dev, VIDIOC_G_FMT, &fmt)) {
+    print_err("VIDIOC_G_FMT", res);
+    return false;
+  }
+
+  notice("v4l2: probing color formats");
+
+  palette = 0;
+  for (counter = 0 ; !palette && counter < sizeof(formats)/sizeof(__u32) ; counter++)
+	  palette = try_video_palette(dev, &fmt, formats[counter]);
+
+  if(palette == 0) {
+    error("device %s doesn't supports grabbing any desired palette", file);
+    return false;
+  }
+
+  notice("v4l2: probing for size");
+
+  fmt.fmt.pix.height = height;
+  fmt.fmt.pix.width = width;
+  res=ioctl(dev, VIDIOC_S_FMT, &fmt);
+  if ( res<0 ) {
+    error("v4l2: size %ix%i not supported res: %i. Got %ux%u", width, height, res, fmt.fmt.pix.width, fmt.fmt.pix.height);
+    return false;
+  }
+
+  errno=0;
+  memset(&reqbuf, 0, sizeof(struct v4l2_requestbuffers));
+  reqbuf.count = BUF_COUNT;
+  reqbuf.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  reqbuf.memory = V4L2_MEMORY_MMAP;
+  res = ioctl(dev, VIDIOC_REQBUFS, &reqbuf);
+  if (res < 0) {
+    print_err("VIDIOC_REQBUFS", res);
+    return false;
+  }
+
+  for (counter = 0; counter < reqbuf.count; counter++) {
+	  memset(&buf, 0, sizeof(struct v4l2_buffer));
+	  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	  buf.memory = V4L2_MEMORY_MMAP;
+	  buf.index = counter;
+	  res = ioctl(dev, VIDIOC_QUERYBUF, &buf);
+	  if (res < 0) {
+    		  print_err("VIDIOC_REQBUFS", res);
+		  return false;
+	  }
+	  buffers[counter].length = buf.length;
+	  buffers[counter].start = mmap (0, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, dev, buf.m.offset);
+	  if (MAP_FAILED == buffers[counter].start) {
+		  perror("mmap failed");
+		  return false;
+	  }
+  }
+  set_filename(file);
+
+  /* set image source and TV norm */
+  grab_chan.channel = input = (channels>1) ? 1 : 0;
+
+  if(have_tuner) { /* does this only if the device has a tuner */
+    _band = 5; /* default band is europe west */
+    _freq = 0;
+    /* resets CHAN */
+    if (-1 == ioctl(dev, VIDIOCGCHAN, &grab_chan)) {
+      print_err("VIDIOCGCHAN", res);
+      return false;
+    }
+
+    if (-1 == ioctl(dev, VIDIOCSCHAN, &grab_chan)) {
+      print_err("VIDIOCSCHAN", res);
+      return false;
+    }
+
+    /* get/set TUNER settings */
+    if (-1 == ioctl(dev, VIDIOCGTUNER, &grab_tuner)) {
+      print_err("VIDIOCGTUNER", res);
+      return false;
+    }
+  }
+
+  rgb_surface = malloc(geo.size);
+
+  notice("V4L2 layer :: w[%u] h[%u] bpp[%u] size[%u]",
+	 geo.w,geo.h,geo.bpp,geo.size,geo);
+
+  type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  res = ioctl(dev, VIDIOC_STREAMON, &type);
+  if (res < 0) {
+    print_err("VIDIOC_STREAMON", res);
+    return false;
+  }
+
+  return true;
+}
+
+bool V4l2Grabber::init(Context *env, int width, int height) {
+    func("%s %s", __FILE__, __FUNCTION__);
+    this->width = width;
+    this->height = height;
+    _init(width,height);
+    return true;
+}
+
+bool V4l2Grabber::init(Context *env) {
+  func("%s %s", __FILE__, __FUNCTION__);
+  return init(env, env->screen->w, env->screen->h);
+}
+
+void V4l2Grabber::set_chan(int ch) {
+
+  grab_chan.channel = input = ch;
+
+  if (-1 == ioctl(dev,VIDIOCGCHAN,&grab_chan))
+    error("error in ioctl VIDIOCGCHAN ");
+
+  grab_chan.norm = VIDEO_MODE_PAL;
+
+  if (-1 == ioctl(dev,VIDIOCSCHAN,&grab_chan))
+    error("error in ioctl VIDIOCSCHAN ");
+
+  act("V4L: input chan %u %s",ch,grab_chan.name);
+  show_osd();
+}
+
+void V4l2Grabber::set_band(int b) {
+  _band = b;
+  chanlist = chanlists[b].list;
+  if(_freq>chanlists[b].count) _freq = chanlists[b].count;
+  act("V4L: frequency table %u %s [%u]",b,chanlists[b].name,chanlists[b].count);
+  show_osd();
+}
+
+void V4l2Grabber::set_freq(int f) {
+  _freq = f;
+
+  unsigned long frequency = chanlist[f].freq*16/1000;
+  float ffreq = (float) frequency/16;
+
+  func("V4L: set frequency %u %.3f",frequency,ffreq);
+
+  //  lock_feed();
+  if (-1 == ioctl(dev,VIDIOCSFREQ,&frequency))
+    error("error in ioctl VIDIOCSFREQ ");
+  //  unlock_feed();
+  act("V4L: frequency %s %.3f Mhz (%s)",chanlist[f].name,ffreq,chanlists[_band].name);
+  show_osd();
+}
+
+
+/* here are defined the keys for this layer */
+bool V4l2Grabber::keypress(int key) {
+  int res = 1;
+
+  switch(key) {
+  case 'k':
+    if(input<channels)
+      set_chan(input+1);
+    break;
+
+  case 'm':
+    if(input>0)
+      set_chan(input-1);
+    break;
+
+    if(have_tuner) {
+    case 'j':
+      if(_band<bandcount)
+	set_band(_band+1);
+      break;
+
+    case 'n':
+      if(_band>0)
+	set_band(_band-1);
+      break;
+
+    case 'h':
+      if(_freq<chanlists[_band].count)
+	set_freq(_freq+1);
+      else
+	set_freq(0);
+      break;
+
+    case 'b':
+      if(_freq>0)
+	set_freq(_freq-1);
+      else
+	set_freq(chanlists[_band].count);
+      break;
+
+    } /* if (have_tuner) */
+
+  default:
+    res = 0;
+  }
+  return res;
+}
+
+void *V4l2Grabber::get_buffer() {
+  return(rgb_surface);
+}
+
+void *V4l2Grabber::feed() {
+
+  memset(&buf, 0, sizeof(struct v4l2_buffer));
+  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  buf.memory = V4L2_MEMORY_MMAP;
+
+  /* FIXME : Should check return values */
+  ioctl(dev, VIDIOC_DQBUF, &buf);
+
+  switch(palette) {
+#if defined HAVE_MMX && !defined HAVE_64BIT
+	case V4L2_PIX_FMT_YUV422P:
+	case V4L2_PIX_FMT_YUYV:
+    		ccvt_yuyv_bgr32(geo.w, geo.h, buffers[buf.index].start, rgb_surface);
+		break;
+#endif
+  	case V4L2_PIX_FMT_YVU420:
+		ccvt_420p_bgr32(width, height, buffers[buf.index].start, rgb_surface);
+		break;
+
+	case V4L2_PIX_FMT_BGR32:
+		memcpy(rgb_surface, buffers[buf.index].start, geo.size);
+		break;
+
+	case V4L2_PIX_FMT_BGR24:
+		ccvt_rgb24_bgr32(width, height, buffers[buf.index].start, rgb_surface);
+		break;
+
+	default:
+		error("video palette %i for layer %s %s not supported",
+				palette, get_name(),get_filename());
+		break;
+  }
+
+  /* FIXME : Should check return values */
+  ioctl(dev, VIDIOC_QBUF, &buf);
+
+  return rgb_surface;
+}
+
+#endif
--- freej-0.9/src/v4l2_layer_js.cpp.v4l2	2007-10-25 14:08:28.000000000 +0200
+++ freej-0.9/src/v4l2_layer_js.cpp	2007-10-25 14:08:28.000000000 +0200
@@ -0,0 +1,84 @@
+/*  FreeJ
+ *  (c) Copyright 2001-2005 Denis Roio aka jaromil <jaromil@dyne.org>
+ *
+ * This source code is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * This source code 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.
+ * Please refer to the GNU Public License for more details.
+ *
+ * You should have received a copy of the GNU Public License along with
+ * this source code; if not, write to:
+ * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * "$Id: freej.cpp 654 2005-08-18 16:52:47Z jaromil $"
+ *
+ */
+
+#include <callbacks_js.h>
+#include <jsparser_data.h>
+#include <config.h>
+
+#ifdef WITH_V4L
+#include <v4l2_layer.h>
+
+DECLARE_CLASS("Cam2Layer",v4l2_layer_class,v4l2_layer_constructor);
+
+////////////////////////////////
+// Video4Linux Layer methods
+JSFunctionSpec v4l2_layer_methods[] = {
+  LAYER_METHODS  ,
+  ENTRY_METHODS  ,
+  //    name		native		        nargs
+  {     "chan",         v4l2_layer_chan,         1},
+  {     "band",         v4l2_layer_band,         1},
+  {     "freq",         v4l2_layer_freq,         1},
+  {0}
+};
+
+JS_CONSTRUCTOR("V4l2Layer", v4l2_layer_constructor, V4l2Grabber);
+JS(v4l2_layer_chan) {
+  func("%u:%s:%s",__LINE__,__FILE__,__FUNCTION__);
+
+  if(argc<1) return JS_FALSE;
+
+  GET_LAYER(V4l2Grabber);
+
+  int chan=JSVAL_TO_INT(argv[0]);
+  lay->set_chan(chan);
+
+  return JS_TRUE;
+}
+JS(v4l2_layer_freq) {
+  func("%u:%s:%s",__LINE__,__FILE__,__FUNCTION__);
+
+  if(argc<1) return JS_FALSE;
+
+  GET_LAYER(V4l2Grabber);
+
+  int freq=JSVAL_TO_INT(argv[0]);
+  lay->set_freq(freq);
+
+  return JS_TRUE;
+}
+JS(v4l2_layer_band) {
+  func("%u:%s:%s",__LINE__,__FILE__,__FUNCTION__);
+
+  if(argc<1) return JS_FALSE;
+
+  GET_LAYER(V4l2Grabber);
+
+  int band=JSVAL_TO_INT(argv[0]);
+  lay->set_band(band);
+
+  return JS_TRUE;
+}
+#endif
+
+
+
+
--- freej-0.9/src/v4l_layer.cpp.v4l2	2007-09-01 20:21:17.000000000 +0200
+++ freej-0.9/src/v4l_layer.cpp	2007-10-25 14:08:28.000000000 +0200
@@ -419,7 +419,7 @@ void *V4lGrabber::feed() {
   else
 #endif
   if(palette == VIDEO_PALETTE_YUV420P) 
-    ccvt_420p_rgb32(width, height, &buffer[grab_map.offsets[ok_frame]], rgb_surface);
+    ccvt_420p_bgr32(width, height, &buffer[grab_map.offsets[ok_frame]], rgb_surface);
 
   else if(palette == VIDEO_PALETTE_RGB32) 
     memcpy(rgb_surface,&buffer[grab_map.offsets[ok_frame]],geo.size);
--- freej-0.9/src/jsparser.cpp.v4l2	2007-09-01 20:21:16.000000000 +0200
+++ freej-0.9/src/jsparser.cpp	2007-10-25 14:08:28.000000000 +0200
@@ -150,6 +150,10 @@ void JsParser::init() {
 		   v4l_layer_class,
 		   v4l_layer_constructor,
 		   v4l_layer_methods);
+    REGISTER_CLASS("Cam2Layer",
+		   v4l2_layer_class,
+		   v4l2_layer_constructor,
+		   v4l2_layer_methods);
 #endif
 
 #ifdef WITH_AVCODEC