Index: trunk/lib/FlairSensorActuator/src/V4LCamera.cpp
===================================================================
--- trunk/lib/FlairSensorActuator/src/V4LCamera.cpp	(revision 338)
+++ trunk/lib/FlairSensorActuator/src/V4LCamera.cpp	(revision 340)
@@ -33,4 +33,31 @@
 #define DEFAULT_V4L_BUFFERS 4
 
+#define CHANNEL_NUMBER 1
+#define CLEAR(x) memset (&(x), 0, sizeof (x))
+#define DEFAULT_V4L_WIDTH  640
+#define DEFAULT_V4L_HEIGHT 480
+#define CV_CAP_PROP_POS_MSEC       0
+#define CV_CAP_PROP_POS_FRAMES     1
+#define CV_CAP_PROP_POS_AVI_RATIO  2
+#define CV_CAP_PROP_FRAME_WIDTH    3
+#define CV_CAP_PROP_FRAME_HEIGHT   4
+#define CV_CAP_PROP_FPS            5
+#define CV_CAP_PROP_FOURCC         6
+#define CV_CAP_PROP_FRAME_COUNT    7
+#define CV_CAP_PROP_FORMAT         8
+#define CV_CAP_PROP_MODE           9
+#define CV_CAP_PROP_BRIGHTNESS    10
+#define CV_CAP_PROP_CONTRAST      11
+#define CV_CAP_PROP_SATURATION    12
+#define CV_CAP_PROP_HUE           13
+#define CV_CAP_PROP_GAIN          14
+#define CV_CAP_PROP_CONVERT_RGB   15
+#define CV_CAP_PROP_SHARPNESS     16
+#define CV_CAP_PROP_EXPOSURE      17
+#define CV_CAP_PROP_AUTOGAIN      18
+#define CV_CAP_PROP_AWB           19
+
+#define HAVE_CAMV4L2
+
 using std::string;
 using namespace flair::core;
@@ -39,5 +66,520 @@
 namespace flair {
 namespace sensor {
-
+  
+  V4LCamera::V4LCamera(string name,
+                     uint8_t camera_index, uint16_t width, uint16_t height,
+                     Image::Type::Format format, uint8_t priority)
+    : Thread(getFrameworkManager(), name, priority),
+      Camera(name, width, height, format) {
+  
+    string deviceName="/dev/video"+std::to_string(camera_index);
+    device = open(deviceName.c_str(), O_RDWR | O_NONBLOCK);
+    if (device == -1) {
+        Thread::Err("Cannot open %s\n",deviceName.c_str());
+    } else {
+        Printf("V4LCamera %s, opened %s\n",name.c_str(),deviceName.c_str());
+    }
+
+    /* w/o memset some parts  arent initialized - AKA: Fill it with zeros so it is clean */
+   memset(&capture,0,sizeof(CvCaptureCAM_V4L));
+   /* Present the routines needed for V4L funtionality.  They are inserted as part of
+      the standard set of cv calls promoting transparency.  "Vector Table" insertion. */
+   capture.FirstCapture = 1;
+   capture.deviceHandle = device;
+  
+     PALETTE_YUYV = 0;
+     PALETTE_UYVY= 0;
+    
+   n_buffers = 0;
+   if (_capture_V4L2 (&capture) == -1) {
+     Thread::Err("_capture_V4L2 failed\n");
+   }
+  
+if (icvSetPropertyCAM_V4L(&capture, CV_CAP_PROP_FRAME_WIDTH, width)<0)
+    Thread::Err("cvSetCaptureProperty error\n");
+  if (icvSetPropertyCAM_V4L(&capture, CV_CAP_PROP_FRAME_HEIGHT, height)<0)
+    Thread::Err("cvSetCaptureProperty error\n");
+
+  if (format == Image::Type::Format::UYVY) {
+    if (icvSetPropertyCAM_V4L(&capture, CV_CAP_PROP_FORMAT, V4L2_PIX_FMT_UYVY)<0)
+      Thread::Err("cvSetCaptureProperty error\n");
+  } else if (format == Image::Type::Format::YUYV) {
+    if (icvSetPropertyCAM_V4L(&capture, CV_CAP_PROP_FORMAT, V4L2_PIX_FMT_YUYV) <
+        0)
+      Thread::Err("cvSetCaptureProperty error\n");
+  } else {
+    Thread::Err("format not supported\n");
+  }
+    // ground station
+    gain = new DoubleSpinBox(GetGroupBox()->NewRow(), "gain:", 0, 1, 0.1);
+    exposure = new DoubleSpinBox(GetGroupBox()->LastRowLastCol(), "exposure:", 0,1, 0.1);
+    bright = new DoubleSpinBox(GetGroupBox()->LastRowLastCol(), "bright:", 0, 1, 0.1);
+    contrast = new DoubleSpinBox(GetGroupBox()->LastRowLastCol(), "contrast:", 0,1, 0.1);
+    hue = new DoubleSpinBox(GetGroupBox()->LastRowLastCol(), "hue:", 0, 1, 0.1);
+    sharpness = new DoubleSpinBox(GetGroupBox()->LastRowLastCol(), "sharpness:", 0, 1, 0.1);
+    sat = new DoubleSpinBox(GetGroupBox()->LastRowLastCol(), "saturation:", 0, 1,0.1);
+    autogain = new CheckBox(GetGroupBox()->NewRow(), "autogain:");
+    autoexposure = new CheckBox(GetGroupBox()->LastRowLastCol(), "autoexposure:");
+    awb = new CheckBox(GetGroupBox()->LastRowLastCol(), "awb:");
+    fps = new Label(GetGroupBox()->NewRow(), "fps");
+
+    hasProblems=false;
+}
+
+V4LCamera::~V4LCamera() {
+    for (int n_buffers = 0; n_buffers < nbBuffers; n_buffers++) {
+       //FreeFunction((char*)buffers[n_buffers].start);
+   }
+    SafeStop();
+    Join();
+}
+int V4LCamera::icvSetPropertyCAM_V4L( CvCaptureCAM_V4L* capture,
+                                  int property_id, double value ){
+    static int width = 0, height = 0;
+    int retval;
+
+    /* initialization */
+    retval = 0;
+
+    /* two subsequent calls setting WIDTH and HEIGHT will change
+       the video size */
+    /* the first one will return an error, though. */
+
+    switch (property_id) {
+    case CV_CAP_PROP_FRAME_WIDTH:
+        width = value;
+        if(width !=0 && height != 0) {
+            retval = icvSetVideoSize( capture, width, height);
+            width = height = 0;
+        }
+        break;
+    case CV_CAP_PROP_FRAME_HEIGHT:
+        height = value;
+        if(width !=0 && height != 0) {
+            retval = icvSetVideoSize( capture, width, height);
+            width = height = 0;
+        }
+        break;
+    case CV_CAP_PROP_FORMAT:
+
+	capture->form.fmt.pix.pixelformat = (unsigned long)value; 
+ 	retval == xioctl (capture->deviceHandle, VIDIOC_S_FMT, &capture->form);
+	if ((unsigned long)value != capture->form.fmt.pix.pixelformat)
+   		retval=-1;
+
+	
+	PALETTE_YUYV = 0;
+	PALETTE_UYVY= 0;
+	
+
+	if ((unsigned long)value== V4L2_PIX_FMT_YUYV)
+	{
+		PALETTE_YUYV = 1;
+	}
+	if ((unsigned long)value== V4L2_PIX_FMT_UYVY)
+	{
+		PALETTE_UYVY = 1;
+	}
+	
+
+	break;
+    case CV_CAP_PROP_BRIGHTNESS:
+    case CV_CAP_PROP_CONTRAST:
+    case CV_CAP_PROP_SATURATION:
+    case CV_CAP_PROP_HUE:
+    case CV_CAP_PROP_GAIN:
+    case CV_CAP_PROP_SHARPNESS:
+    case CV_CAP_PROP_EXPOSURE:
+    case CV_CAP_PROP_AUTOGAIN:
+    case CV_CAP_PROP_AWB:
+        retval = icvSetControl(capture, property_id, value);
+        break;
+    default:
+        fprintf(stderr,
+                "HIGHGUI ERROR: V4L: setting property #%d is not supported\n",
+                property_id);
+    }
+
+    /* return the the status */
+    return retval;
+}
+int V4LCamera::icvSetControl (CvCaptureCAM_V4L* capture,
+                          int property_id, double value) {
+  
+  /* limitation of the input value */
+  if (value < 0.0) {
+    value = 0.0;
+  } else if (value > 1.0) {
+    value = 1.0;
+  }
+
+
+    /* default value for min and max */
+    int v4l2_min = 0;
+    int v4l2_max = 255;
+
+    /* initialisations */
+    CLEAR (capture->control);
+
+    /* set which control we want to set */
+    switch (property_id) {
+
+    case CV_CAP_PROP_BRIGHTNESS:
+        capture->control.id = V4L2_CID_BRIGHTNESS;
+        break;
+    case CV_CAP_PROP_CONTRAST:
+        capture->control.id = V4L2_CID_CONTRAST;
+        break;
+    case CV_CAP_PROP_SATURATION:
+        capture->control.id = V4L2_CID_SATURATION;
+        break;
+    case CV_CAP_PROP_HUE:
+        capture->control.id = V4L2_CID_HUE;
+        break;
+    case CV_CAP_PROP_GAIN:
+        capture->control.id = V4L2_CID_GAIN;
+        break;
+    case CV_CAP_PROP_SHARPNESS:
+        capture->control.id = V4L2_CID_SHARPNESS;
+        break;
+    case CV_CAP_PROP_EXPOSURE:
+        capture->control.id = V4L2_CID_EXPOSURE;
+        break;
+    case CV_CAP_PROP_AUTOGAIN:
+        capture->control.id = V4L2_CID_AUTOGAIN;
+        break;
+    case CV_CAP_PROP_AWB:
+        capture->control.id = V4L2_CID_AUTO_WHITE_BALANCE;
+	break;
+    default:
+        fprintf(stderr,
+                "HIGHGUI ERROR: V4L2: setting property #%d is not supported\n",
+                property_id);
+        return -1;
+    }
+
+    /* get the min and max values */
+    if (-1 == xioctl (capture->deviceHandle,
+                      VIDIOC_G_CTRL, &capture->control)) {
+//          perror ("VIDIOC_G_CTRL for getting min/max values");
+          return -1;
+    }
+
+    /* get the min/max values */
+    switch (property_id) {
+
+    case CV_CAP_PROP_BRIGHTNESS:
+        v4l2_min = capture->v4l2_brightness_min;
+        v4l2_max = capture->v4l2_brightness_max;
+        break;
+    case CV_CAP_PROP_CONTRAST:
+        v4l2_min = capture->v4l2_contrast_min;
+        v4l2_max = capture->v4l2_contrast_max;
+        break;
+    case CV_CAP_PROP_SATURATION:
+        v4l2_min = capture->v4l2_saturation_min;
+        v4l2_max = capture->v4l2_saturation_max;
+        break;
+    case CV_CAP_PROP_HUE:
+        v4l2_min = capture->v4l2_hue_min;
+        v4l2_max = capture->v4l2_hue_max;
+        break;
+    case CV_CAP_PROP_GAIN:
+        v4l2_min = capture->v4l2_gain_min;
+        v4l2_max = capture->v4l2_gain_max;
+	break;
+    case CV_CAP_PROP_SHARPNESS:
+        v4l2_min = capture->v4l2_sharpness_min;
+        v4l2_max = capture->v4l2_sharpness_max;
+	break;
+    case CV_CAP_PROP_EXPOSURE:
+        v4l2_min = capture->v4l2_exposure_min;
+        v4l2_max = capture->v4l2_exposure_max;
+        break;
+    case CV_CAP_PROP_AUTOGAIN:
+        v4l2_min = capture->v4l2_autogain_min;
+        v4l2_max = capture->v4l2_autogain_max;
+        break;
+    case CV_CAP_PROP_AWB:
+        v4l2_min = capture->v4l2_awb_min;
+        v4l2_max = capture->v4l2_awb_max;
+        break;
+    }
+
+    /* initialisations */
+    CLEAR (capture->control);
+
+    /* set which control we want to set */
+    switch (property_id) {
+
+    case CV_CAP_PROP_BRIGHTNESS:
+        capture->control.id = V4L2_CID_BRIGHTNESS;
+        break;
+    case CV_CAP_PROP_CONTRAST:
+        capture->control.id = V4L2_CID_CONTRAST;
+        break;
+    case CV_CAP_PROP_SATURATION:
+        capture->control.id = V4L2_CID_SATURATION;
+        break;
+    case CV_CAP_PROP_HUE:
+        capture->control.id = V4L2_CID_HUE;
+        break;
+    case CV_CAP_PROP_GAIN:
+        capture->control.id = V4L2_CID_GAIN;
+        break;
+   case CV_CAP_PROP_SHARPNESS:
+        capture->control.id = V4L2_CID_SHARPNESS;
+        break;
+    case CV_CAP_PROP_EXPOSURE:
+        capture->control.id = V4L2_CID_EXPOSURE;
+        break;
+    case CV_CAP_PROP_AUTOGAIN:
+        capture->control.id = V4L2_CID_AUTOGAIN;
+        break;
+    case CV_CAP_PROP_AWB:
+        capture->control.id = V4L2_CID_AUTO_WHITE_BALANCE;
+        break;
+    default:
+        fprintf(stderr,
+                "HIGHGUI ERROR: V4L2: setting property #%d is not supported\n",
+                property_id);
+        return -1;
+    }
+
+    /* set the value we want to set to the scaled the value */
+    capture->control.value = (int)(value * (v4l2_max - v4l2_min) + v4l2_min);
+
+    /* The driver may clamp the value or return ERANGE, ignored here */
+    if (-1 == xioctl (capture->deviceHandle,
+                      VIDIOC_S_CTRL, &capture->control) && errno != ERANGE) {
+        perror ("VIDIOC_S_CTRL");
+        return -1;
+    }
+
+  /* all was OK */
+  return 0;
+
+}
+int V4LCamera::_capture_V4L2 (CvCaptureCAM_V4L *capture)
+{
+   int detect_v4l2 = 0;
+
+   detect_v4l2 = try_init_v4l2(capture);
+
+   if (detect_v4l2 != 1) {
+       /* init of the v4l2 device is not OK */
+       return -1;
+   }
+
+   /* Init V4L2 control variables */
+   capture->v4l2_brightness = 0;
+   capture->v4l2_contrast = 0;
+   capture->v4l2_saturation = 0;
+   capture->v4l2_hue = 0;
+   capture->v4l2_gain = 0;
+   capture->v4l2_sharpness = 0;
+   capture->v4l2_exposure = 0;
+   capture->v4l2_autogain = 0;
+   capture->v4l2_awb = 0;
+
+   capture->v4l2_brightness_min = 0;
+   capture->v4l2_contrast_min = 0;
+   capture->v4l2_saturation_min = 0;
+   capture->v4l2_hue_min = 0;
+   capture->v4l2_gain_min = 0;
+   capture->v4l2_sharpness_min = 0;
+   capture->v4l2_exposure_min = 0;
+   capture->v4l2_autogain_min = 0;
+   capture->v4l2_awb_min = 0;
+
+   capture->v4l2_brightness_max = 0;
+   capture->v4l2_contrast_max = 0;
+   capture->v4l2_saturation_max = 0;
+   capture->v4l2_hue_max = 0;
+   capture->v4l2_gain_max = 0;
+   capture->v4l2_sharpness_max = 0;
+   capture->v4l2_exposure_max = 0;
+   capture->v4l2_autogain_max = 0;
+   capture->v4l2_awb_max = 0;
+     
+  
+   if ((capture->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {
+      /* Nope. */
+      fprintf( stderr, "HIGHGUI ERROR: V4L2: device is unable to capture video memory.\n");
+      
+      return -1;
+   }
+
+  
+
+   /* Find Window info */
+   CLEAR (capture->form);
+   capture->form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+        
+   if (-1 == xioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form)) {
+       fprintf( stderr, "HIGHGUI ERROR: V4L2: Could not obtain specifics of capture window.\n\n");
+       
+       return -1;
+   }
+
+  
+
+   if (autosetup_capture_mode_v4l2(capture) == -1)
+       return -1;
+
+   icvSetVideoSize(capture, DEFAULT_V4L_WIDTH, DEFAULT_V4L_HEIGHT);
+
+   unsigned int min;
+
+   /* Buggy driver paranoia. */
+   min = capture->form.fmt.pix.width * 2;
+
+   if (capture->form.fmt.pix.bytesperline < min)
+       capture->form.fmt.pix.bytesperline = min;
+
+   min = capture->form.fmt.pix.bytesperline * capture->form.fmt.pix.height;
+ 
+   if (capture->form.fmt.pix.sizeimage < min)
+       capture->form.fmt.pix.sizeimage = min;
+
+   return 1;
+}
+int V4LCamera::icvSetVideoSize( CvCaptureCAM_V4L* capture, int w, int h) {
+
+
+
+    CLEAR (capture->crop);
+    capture->crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    capture->crop.c.left       = 0; 
+    capture->crop.c.top        = 0; 
+    capture->crop.c.height     = h*24;
+    capture->crop.c.width      = w*24;
+
+    /* set the crop area, but don't exit if the device don't support croping */
+    xioctl (capture->deviceHandle, VIDIOC_S_CROP, &capture->crop);
+
+    CLEAR (capture->form);
+    capture->form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+    /* read the current setting, mainly to retreive the pixelformat information */
+    xioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form);
+
+    /* set the values we want to change */
+    capture->form.fmt.pix.width = w; 
+    capture->form.fmt.pix.height = h;
+    capture->form.fmt.win.chromakey = 0;
+    capture->form.fmt.win.field = V4L2_FIELD_ANY;
+    capture->form.fmt.win.clips = 0;
+    capture->form.fmt.win.clipcount = 0;
+    capture->form.fmt.pix.field = V4L2_FIELD_ANY;
+
+    /* ask the device to change the size
+     * don't test if the set of the size is ok, because some device
+     * don't allow changing the size, and we will get the real size
+     * later */
+    xioctl (capture->deviceHandle, VIDIOC_S_FMT, &capture->form);
+
+    /* try to set framerate to 30 fps */
+    struct v4l2_streamparm setfps;  
+    memset (&setfps, 0, sizeof(struct v4l2_streamparm));
+    setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    setfps.parm.capture.timeperframe.numerator = 1;
+    setfps.parm.capture.timeperframe.denominator = 30;
+    xioctl (capture->deviceHandle, VIDIOC_S_PARM, &setfps);
+
+    /* we need to re-initialize some things, like buffers, because the size has
+     * changed */
+    capture->FirstCapture = 1;
+
+    /* Get window info again, to get the real value */
+    if (-1 == xioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form))
+    {
+      fprintf(stderr, "HIGHGUI ERROR: V4L/V4L2: Could not obtain specifics of capture window.\n\n");
+
+      
+
+      return 0;
+    }
+
+    return 0;
+
+  
+
+   
+  return 0;
+
+}
+int V4LCamera::try_palette_v4l2(CvCaptureCAM_V4L* capture, unsigned long colorspace)
+{
+  CLEAR (capture->form);
+
+  capture->form.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  capture->form.fmt.pix.pixelformat = colorspace;
+  capture->form.fmt.pix.field       = V4L2_FIELD_ANY;
+  capture->form.fmt.pix.width = DEFAULT_V4L_WIDTH;
+  capture->form.fmt.pix.height = DEFAULT_V4L_HEIGHT;
+  
+  if (-1 == xioctl (capture->deviceHandle, VIDIOC_S_FMT, &capture->form))
+      return -1;
+
+  
+  if (colorspace != capture->form.fmt.pix.pixelformat)
+    return -1;
+  else
+    return 0;
+}
+int V4LCamera::autosetup_capture_mode_v4l2(CvCaptureCAM_V4L* capture)
+{
+  if (try_palette_v4l2(capture, V4L2_PIX_FMT_YUYV) == 0) {
+    PALETTE_YUYV = 1;
+  } else if (try_palette_v4l2(capture, V4L2_PIX_FMT_UYVY) == 0) {
+    PALETTE_UYVY = 1;
+  } else {
+	fprintf(stderr, "HIGHGUI ERROR: V4L2: Pixel format of incoming image is unsupported by OpenCV\n");
+   
+    return -1;
+  }
+  
+  return 0;
+
+}
+
+
+
+int V4LCamera::try_init_v4l2(CvCaptureCAM_V4L* capture)
+{
+
+  // if detect = -1 then unable to open device
+  // if detect = 0 then detected nothing
+  // if detect = 1 then V4L2 device 
+  int detect = 0;
+
+
+  if (detect == 0)
+  {
+    CLEAR (capture->cap);
+    if (-1 == xioctl (capture->deviceHandle, VIDIOC_QUERYCAP, &capture->cap))
+    {
+      detect = 0;
+
+      
+    }
+      else
+    {
+      CLEAR (capture->capability);
+      capture->capability.type = capture->cap.capabilities;
+     
+      /* Query channels number */
+      if (-1 != xioctl (capture->deviceHandle, VIDIOC_G_INPUT, &capture->capability.channels))
+      {
+        detect = 1;
+      }
+    }
+  }
+
+  return detect;
+
+}
+/*
 V4LCamera::V4LCamera(string name,
                      uint8_t camera_index, uint16_t width, uint16_t height,
@@ -221,5 +763,362 @@
   close(device);
 }
-
+*/
+int V4LCamera::v4l2_alloc_buffers (CvCaptureCAM_V4L *capture, char *deviceName)
+{
+   CLEAR (capture->req);
+   
+   unsigned int buffer_number = DEFAULT_V4L_BUFFERS;
+
+   try_again:
+   
+   capture->req.count = buffer_number;
+   capture->req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+   capture->req.memory = V4L2_MEMORY_MMAP;
+
+   if (-1 == xioctl (capture->deviceHandle, VIDIOC_REQBUFS, &capture->req))
+   {
+       if (EINVAL == errno)
+       {
+         fprintf (stderr, "%s does not support memory mapping\n", deviceName);
+       } else {
+         perror ("VIDIOC_REQBUFS");
+       }
+       /* free capture, and returns an error code */
+       
+       return -1;
+   }
+
+   if (capture->req.count < buffer_number)
+   {
+       if (buffer_number == 1)
+       {
+           fprintf (stderr, "Insufficient buffer memory on %s\n", deviceName);
+
+           /* free capture, and returns an error code */
+           
+           return -1;
+       } else {
+         buffer_number--;
+	 fprintf (stderr, "Insufficient buffer memory on %s -- decreaseing buffers\n", deviceName);
+	 
+	 goto try_again;
+       }
+   }
+
+   for (n_buffers = 0; n_buffers < capture->req.count; ++n_buffers)
+   {
+       struct v4l2_buffer buf;
+
+       CLEAR (buf);
+
+       buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       buf.memory = V4L2_MEMORY_MMAP;
+       buf.index = n_buffers;
+
+       if (-1 == xioctl (capture->deviceHandle, VIDIOC_QUERYBUF, &buf)) {
+           perror ("VIDIOC_QUERYBUF");
+       
+           /* free capture, and returns an error code */
+           
+           return -1;
+       }
+
+       capture->buffers[n_buffers].length = buf.length;
+       capture->buffers[n_buffers].start =
+         mmap (NULL /* start anywhere */,
+               buf.length,
+               PROT_READ | PROT_WRITE /* required */,
+               MAP_SHARED /* recommended */,
+               capture->deviceHandle, buf.m.offset);
+
+       if (MAP_FAILED == capture->buffers[n_buffers].start) {
+           perror ("mmap");
+       
+           /* free capture, and returns an error code */
+           
+           return -1;
+       }
+
+
+   }
+
+   /* Set up Image data */
+   /*
+   cvInitImageHeader( &capture->frame,
+                      cvSize( capture->captureWindow.width,
+                              capture->captureWindow.height ),
+                      IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4 );*/
+   /* Allocate space for RGBA data */
+   capture->imageSize=capture->form.fmt.pix.width*capture->form.fmt.pix.height*2;
+   capture->imageData = AllocFunction(capture->imageSize);
+   Printf("cmem allocated %i at %x\n",capture->imageSize,capture->imageData);
+   
+   return 1;
+};
+int V4LCamera::cvGrabFrame(CvCaptureCAM_V4L* capture) {
+
+   if (capture->FirstCapture) { 
+      /* Some general initialization must take place the first time through */
+
+      /* This is just a technicality, but all buffers must be filled up before any
+         staggered SYNC is applied.  SO, filler up. (see V4L HowTo) */
+
+
+	v4l2_alloc_buffers (capture, NULL);
+
+        for (capture->bufferIndex = 0;
+             capture->bufferIndex < ((int)capture->req.count);
+             ++capture->bufferIndex)
+        {
+
+          struct v4l2_buffer buf;
+
+          CLEAR (buf);
+
+          buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+          buf.memory      = V4L2_MEMORY_MMAP;
+          buf.index       = (unsigned long)capture->bufferIndex;
+
+          if (-1 == xioctl (capture->deviceHandle, VIDIOC_QBUF, &buf)) {
+              perror ("VIDIOC_QBUF");
+              return 0;
+          }
+        }
+
+        /* enable the streaming */
+        capture->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+        if (-1 == xioctl (capture->deviceHandle, VIDIOC_STREAMON,
+                          &capture->type)) {
+            /* error enabling the stream */
+            perror ("VIDIOC_STREAMON");
+            return 0;
+        }
+
+      
+
+
+      /* preparation is ok */
+      capture->FirstCapture = 0;
+   }
+
+
+
+     mainloop_v4l2(capture);
+
+
+
+   return(1);
+}
+void V4LCamera::mainloop_v4l2(CvCaptureCAM_V4L* capture) {
+    unsigned int count;
+
+    count = 1;
+
+    while (count-- > 0) {
+        for (;;) {
+            fd_set fds;
+            struct timeval tv;
+            int r;
+
+            FD_ZERO (&fds);
+            FD_SET (capture->deviceHandle, &fds);
+
+            /* Timeout. */
+            tv.tv_sec = 2;
+            tv.tv_usec = 0;
+
+            r = select (capture->deviceHandle+1, &fds, NULL, NULL, &tv);
+
+            if (-1 == r) {
+                if (EINTR == errno)
+                    continue;
+
+                perror ("select");
+            }
+
+            if (0 == r) {
+                fprintf (stderr, "select timeout\n");
+
+                /* end the infinite loop */
+                break;
+            }
+
+            if (read_frame_v4l2 (capture))
+                break;
+        }
+    }
+}
+int V4LCamera::read_frame_v4l2(CvCaptureCAM_V4L* capture) {
+    struct v4l2_buffer buf;
+
+    CLEAR (buf);
+
+    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    buf.memory = V4L2_MEMORY_MMAP;
+
+    if (-1 == xioctl (capture->deviceHandle, VIDIOC_DQBUF, &buf)) {
+        switch (errno) {
+        case EAGAIN:
+            return 0;
+
+        case EIO:
+            /* Could ignore EIO, see spec. */
+
+            /* fall through */
+
+        default:
+            /* display the error and stop processing */
+            perror ("VIDIOC_DQBUF");
+            return 1;
+        }
+   }
+
+   if(buf.index >= capture->req.count) {
+     Thread::Err("buf.index >= capture->req.count\n");
+   }
+   
+
+   capture->bufferIndex = buf.index;
+
+
+   if (-1 == xioctl (capture->deviceHandle, VIDIOC_QBUF, &buf))
+       perror ("VIDIOC_QBUF");
+
+   return 1;
+}
+void V4LCamera::Run(void) {
+  Time cam_time, new_time, fpsNow, fpsPrev;
+  //IplImage *img; // raw image
+  int fpsCounter = 0;
+
+  // init image old
+  if (!cvGrabFrame(&capture)) {
+    Printf("Could not grab a frame\n");
+  }
+  cam_time = GetTime();
+  fpsPrev = cam_time;
+
+  while (!ToBeStopped()) {
+    
+   
+    // fps counter
+    fpsCounter++;
+    if (fpsCounter == 100) {
+      fpsNow = GetTime();
+      fps->SetText("fps: %.1f",
+       fpsCounter / ((float)(fpsNow - fpsPrev) / 1000000000.));
+      fpsCounter = 0;
+      fpsPrev = fpsNow;
+    }
+
+    // cam properties
+    if (gain->ValueChanged() == true && autogain->Value() == false)
+      SetGain(gain->Value());
+    if (exposure->ValueChanged() == true && autoexposure->Value() == false)
+      SetExposure(exposure->Value());
+    if (bright->ValueChanged() == true)
+      SetBrightness(bright->Value());
+    if (sat->ValueChanged() == true)
+      SetSaturation(sat->Value());
+    if (contrast->ValueChanged() == true)
+      SetContrast(contrast->Value());
+    if (hue->ValueChanged() == true)
+      SetHue(hue->Value());
+    //if (sharpness->ValueChanged() == true)
+    //  cvSetCaptureProperty(capture, CV_CAP_PROP_SHARPNESS, sharpness->Value());
+    if (autogain->ValueChanged() == true) {
+      if (autogain->Value() == true) {
+        gain->setEnabled(false);
+      } else {
+        gain->setEnabled(true);
+        SetGain(gain->Value());
+      }
+      SetAutoGain(autogain->Value());
+    }
+    if (autoexposure->ValueChanged() == true) {
+      if (autoexposure->Value() == true) {
+        exposure->setEnabled(false);
+      } else {
+        exposure->setEnabled(true);
+        SetExposure(exposure->Value());
+      }
+      SetAutoExposure(autoexposure->Value());
+    }
+    //if (awb->ValueChanged() == true)
+    //  cvSetCaptureProperty(capture, CV_CAP_PROP_AWB, awb->Value());
+   
+    // cam pictures
+    cvRetrieveRawFrame(&capture);
+    if (!cvGrabFrame(&capture)) {
+      Printf("Could not grab a frame\n");
+    }
+    new_time = GetTime();
+        
+    //check for ps3eye deconnection in hds uav
+    if(new_time-cam_time>100*1000*1000) {
+      Thread::Warn("delta trop grand\n");
+      hasProblems=true;
+    }
+
+    output->GetMutex();
+    
+    output->buffer=capture.imageData;
+    output->ReleaseMutex();
+   
+    output->SetDataTime(cam_time);
+    ProcessUpdate(output);
+    cam_time = new_time;
+  }
+
+  //cvReleaseCapture(&capture);
+}
+
+void V4LCamera::cvRetrieveRawFrame( CvCaptureCAM_V4L* capture) {
+
+
+
+
+   /* Now get what has already been captured as a IplImage return */
+
+   /* First, reallocate imageData if the frame size changed */
+
+
+/*
+    if(((unsigned long)capture->frame.width != capture->form.fmt.pix.width)
+       || ((unsigned long)capture->frame.height != capture->form.fmt.pix.height)) {
+           if (PALETTE_YUYV == 1 || PALETTE_UYVY == 1)
+           {
+                cvFree(&capture->frame.imageData);
+                cvInitImageHeader( &capture->frame,
+                cvSize( capture->form.fmt.pix.width,
+                capture->form.fmt.pix.height ),
+                IPL_DEPTH_8U,2, IPL_ORIGIN_TL, 4 );
+                capture->frame.imageData = (char *)cvAlloc(capture->frame.imageSize);
+           }else
+           {
+              fprintf( stderr,
+                 "HIGHGUI ERROR: V4L: raw output not supported for this palette\n");
+           }
+
+    }
+
+ */
+
+
+    if (PALETTE_YUYV == 1){
+         memcpy((char *)capture->imageData,
+             (char *)capture->buffers[capture->bufferIndex].start,
+             capture->imageSize);
+    }
+    if (PALETTE_UYVY == 1){
+        memcpy((char *)capture->imageData,
+             (char *)capture->buffers[capture->bufferIndex].start,
+             capture->imageSize);
+    }
+  
+ 
+
+   
+}
 int V4LCamera::QueueBuffer(int index) {
     struct v4l2_buffer buf;
