Index: /trunk/lib/FlairSensorActuator/src/V4LCamera.cpp
===================================================================
--- /trunk/lib/FlairSensorActuator/src/V4LCamera.cpp	(revision 351)
+++ /trunk/lib/FlairSensorActuator/src/V4LCamera.cpp	(revision 352)
@@ -17,21 +17,10 @@
 
 #include "V4LCamera.h"
-#include <GroupBox.h>
-#include <DoubleSpinBox.h>
-#include <CheckBox.h>
-#include <Label.h>
+#include "V4LCamera_impl.h"
 #include <Image.h>
 #include <FrameworkManager.h>
-#include <fcntl.h>
-//#include <linux/videodev2.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <cstring>
-#include <sys/mman.h>
-#include <VisionFilter.h>
 
 using std::string;
 using namespace flair::core;
-using namespace flair::gui;
 
 namespace flair {
@@ -43,266 +32,16 @@
       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());
-  }
-
-  if(format == Image::Type::Format::UYVY) {
-    if(Init(width,height,V4L2_PIX_FMT_UYVY) == -1) {
-     Thread::Err("initialisation failed\n");
-    }
-  } else if (format == Image::Type::Format::YUYV) {
-    if(Init(width,height,V4L2_PIX_FMT_YUYV) == -1) {
-     Thread::Err("initialisation failed\n");
-    }
-  } else {
-    Thread::Err("format not supported\n");
-  }
-  
-  //todo: better handling of detection, only neeeded for omap/dm
-  //also in run, copy from v4l to cmem is not necessary if not using cmem...
-#ifdef ARMV7A
-  useMemoryUsrPtr=true;
-#else
-  useMemoryUsrPtr=false;
-#endif
-  if(useMemoryUsrPtr) {
-    AllocUserBuffers();
-  } else {
-    AllocV4LBuffers();
-  }
-  
-  for (int i=0;i < nbBuffers;i++) {
-    QueueBuffer(i);
-  }
-
-  /* enable the streaming */
-  v4l2_buf_type type;
-  type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-  if (-1 == xioctl (device, VIDIOC_STREAMON,&type)) {
-    Thread::Err("VIDIOC_STREAMON error\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;
+  pimpl_=new V4LCamera_impl(this,name,camera_index,width,height,format);
 }
 
 V4LCamera::~V4LCamera() {
-  if(useMemoryUsrPtr) {
-    for (int i = 0; i < nbBuffers; i++) {
-      FreeFunction((char*)buffers[i]);
-    }
-  } else {
-      FreeFunction(imageData);
-  }
   SafeStop();
   Join();
-  close(device);
-}
-
-int V4LCamera::Init(int width, int height,unsigned long colorspace) {
-  struct v4l2_capability cap;
-  memset(&cap, 0, sizeof (v4l2_capability));
-  
-  if(-1 == xioctl(device, VIDIOC_QUERYCAP, &cap)) {
-    return -1;
-  }
-     
-  if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {
-    Thread::Err("device is unable to capture video memory.\n");
-    return -1;
-  }
-
-  struct v4l2_format form;
-  memset(&form, 0, sizeof (v4l2_format));
-  form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-  /* read the current setting */
-  if(-1 == xioctl(device, VIDIOC_G_FMT, &form)) {
-   Thread::Err("Could not obtain specifics of capture window.\n");
-   return -1;
-  }
-
-  /* set the values we want to change */
-  form.fmt.pix.width = width; 
-  form.fmt.pix.height = height;
-  form.fmt.win.chromakey = 0;
-  form.fmt.win.field = V4L2_FIELD_ANY;
-  form.fmt.win.clips = 0;
-  form.fmt.win.clipcount = 0;
-  form.fmt.pix.field = V4L2_FIELD_ANY;
-  form.fmt.pix.pixelformat = colorspace;
-
-  /* ask the device to change the size*/
-  if(-1 == xioctl (device, VIDIOC_S_FMT, &form)) {
-    Thread::Err("Could not set specifics of capture window.\n");
-    return -1;
-  }
-  
-  return 0;
-}
-
-int V4LCamera::AllocV4LBuffers() {
-  struct v4l2_requestbuffers req;
-  memset(&req, 0, sizeof (v4l2_requestbuffers));
-  nbBuffers=DEFAULT_V4L_BUFFERS;
-
-  try_again:
-
-  req.count = nbBuffers;
-  req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-  req.memory = V4L2_MEMORY_MMAP;
-
-  if(-1 == xioctl(device, VIDIOC_REQBUFS, &req)) {
-    if (EINVAL == errno) {
-      Thread::Err("camera does not support memory mapping\n");
-    } else {
-      Thread::Err("VIDIOC_REQBUFS failed\n");
-    }
-    return -1;
-  }
-
-  if(req.count < nbBuffers) {
-    if (nbBuffers == 1) {
-      Thread::Err("Insufficient buffer memory\n");
-      return -1;
-    } else {
-      nbBuffers--;
-      Thread::Warn("Insufficient buffer memory -- decreaseing buffers to %i\n",nbBuffers);
-      goto try_again;
-    }
-  }
-
-  for(int i=0; i<req.count; i++) {
-    struct v4l2_buffer buf;
-    memset(&buf, 0, sizeof (v4l2_buffer));
-
-    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    buf.memory = V4L2_MEMORY_MMAP;
-    buf.index = i;
-
-    if(-1 == xioctl(device, VIDIOC_QUERYBUF, &buf)) {
-      Thread::Err("VIDIOC_QUERYBUF error\n");
-      return -1;
-    }
-
-    if(output->GetDataType().GetSize()!=buf.length) {
-      Thread::Err("buf size is not as exepcted %i/%i\n",buf.length,output->GetDataType().GetSize());
-      return -1;
-    }
-
-    buffers[i]=mmap(NULL,buf.length,PROT_READ | PROT_WRITE,MAP_SHARED,device, buf.m.offset);
-
-    if(MAP_FAILED == buffers[i]) {
-      Thread::Err("mmap error\n");
-      return -1;
-    }
-  }
-
-  //allocate output data
-  imageData = AllocFunction(output->GetDataType().GetSize());
-  //Printf("cmem allocated %i at %x\n",output->GetDataType().GetSize(),imageData);
-
-  return 1;
-};
-
-int V4LCamera::AllocUserBuffers(void) {
-  struct v4l2_requestbuffers req;
-  memset(&req, 0, sizeof (v4l2_requestbuffers));
-  nbBuffers=DEFAULT_V4L_BUFFERS;
-
-  req.count = nbBuffers;
-  req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-  req.memory = V4L2_MEMORY_USERPTR;
-
-  if (xioctl (device, VIDIOC_REQBUFS, &req)==-1) {
-    if (errno==EINVAL) {
-      Thread::Err("VIDIOC_REQBUFS user memory not supported\n");
-    } else {
-      Thread::Err ("VIDIOC_REQBUFS xioctl\n");
-    }
-    return -1;
-  }
-
-  for (int i=0; i<nbBuffers; i++) {
-    buffers[i] =AllocFunction(output->GetDataType().GetSize());
-  }
-
-  return 1;
-};
-
-int V4LCamera::GrabFrame(void) {
-  fd_set fds;
-  struct timeval tv;
-  FD_ZERO (&fds);
-  FD_SET (device, &fds);
-
-  tv.tv_sec = 0;
-  tv.tv_usec = 100000;
-
-  int r=select(device+1, &fds, NULL, NULL, &tv);
-
-  if (r==-1) {
-    char errorMsg[256];
-    Thread::Err("select (%s)\n", strerror_r(-r, errorMsg, sizeof(errorMsg)));
-    return -1;
-  }
-
-  if (r==0) {
-    Thread::Err("select timeout\n");
-    return -1;
-  }
-  
-  struct v4l2_buffer buf;
-  memset(&buf, 0, sizeof (v4l2_buffer));
-  buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
-  if(useMemoryUsrPtr) {
-    buf.memory=V4L2_MEMORY_USERPTR;
-  } else {
-    buf.memory=V4L2_MEMORY_MMAP;
-  }
-
-   //get last captured buffer
-  dQueuedBuffer.index=-1;
-  for(int i=0;i<nbBuffers;i++) {
-    if (xioctl (device, VIDIOC_DQBUF, &buf)==-1) {
-      if (errno==EAGAIN) {//when no new buffer is available for reading (non blocking)
-        //Printf("%s eagain\n",Thread::ObjectName().c_str());
-        break;
-      } else {
-        Thread::Err("VIDIOC_DQBUF xioctl\n");
-        return -1;
-      }
-    } else {
-      //Printf("%s %i dqueued\n",Thread::ObjectName().c_str(),buf.index);
-      //Printf("%i %x %i %i\n",buf.bytesused,buf.flags,buf.field,buf.sequence);
-      if(dQueuedBuffer.index!=-1) {
-        //Printf("%s %i queued\n",Thread::ObjectName().c_str(),dQueuedBuffer.index);
-        QueueBuffer(&dQueuedBuffer);
-      }
-      dQueuedBuffer=buf;
-    }
-  }
-  //Printf("%s %i\n",Thread::ObjectName().c_str(),dQueuedBuffer.index);
-
-  return 1;
+  delete pimpl_;
 }
 
 void V4LCamera::Run(void) {
+  pimpl_->Run();
+  /*
   Time cam_time, new_time, fpsNow, fpsPrev;
   int fpsCounter = 0;
@@ -368,14 +107,5 @@
       Thread::Warn("delta t trop grand\n");
       hasProblems=true;
-    }/*
-    if(hasProblems==false) {
-      struct v4l2_format form;
-      form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-      xioctl(device, VIDIOC_G_FMT,&form);
-      if(xioctl (device, VIDIOC_G_FMT,&form)<0) {
-        Thread::Warn("camera disconnected\n");
-        hasProblems=true;
-      }
-    }*/
+    }
 
     //select buffer
@@ -400,39 +130,13 @@
     }
   }
-}
-
-int V4LCamera::QueueBuffer(struct v4l2_buffer *buf) {
-  if(buf->index>=0 && buf->index<nbBuffers) {
-    int ret=xioctl (device, VIDIOC_QBUF,buf);
-    if (ret==-1) {
-      Thread::Err("VIDIOC_QBUF xioctl %s\n",strerror(-ret));
-      return -1;
-    }
-  }
-  return 0;
-}
-
-int V4LCamera::QueueBuffer(int index) {
-  struct v4l2_buffer buf;
-  memset(&buf, 0, sizeof (v4l2_buffer));
-  
-  buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
-  buf.index=(unsigned long)index;
-  if(useMemoryUsrPtr) {
-    buf.memory=V4L2_MEMORY_USERPTR;
-    buf.m.userptr=(unsigned long)(buffers[index]);
-    buf.length=output->GetDataType().GetSize();
-  } else {
-    buf.memory=V4L2_MEMORY_MMAP;
-  }
-  return QueueBuffer(&buf);
+   */
 }
 
 bool V4LCamera::HasProblems(void) {
-  return hasProblems;
+  return pimpl_->hasProblems;
 }
 
 void V4LCamera::SetAutoGain(bool value) {
-  SetProperty(V4L2_CID_AUTOGAIN, value);
+  pimpl_->SetAutoGain(value);
 }
 
@@ -442,71 +146,25 @@
 
 void V4LCamera::SetGain(float value) {
-  SetProperty(V4L2_CID_GAIN, value);
+  pimpl_->SetGain(value);
 }
 
 void V4LCamera::SetExposure(float value) {
-  SetProperty(V4L2_CID_EXPOSURE, value);
+  pimpl_->SetExposure(value);
 }
 
 void V4LCamera::SetBrightness(float value) {
-  SetProperty(V4L2_CID_BRIGHTNESS, value);
+  pimpl_->SetBrightness(value);
 }
 
 void V4LCamera::SetSaturation(float value) {
-  SetProperty(V4L2_CID_SATURATION, value);
+  pimpl_->SetSaturation(value);
 }
 
 void V4LCamera::SetHue(float value) {
-  SetProperty(V4L2_CID_HUE, value);
+  pimpl_->SetHue(value);
 }
 
 void V4LCamera::SetContrast(float value) {
-  SetProperty(V4L2_CID_CONTRAST, value);
-}
-
-float V4LCamera::GetProperty(int property) {
-  //get min and max value
-  struct v4l2_queryctrl queryctrl;
-  queryctrl.id = property;
-  if(xioctl (device, VIDIOC_QUERYCTRL,&queryctrl)==-1) return -1;
-  int min = queryctrl.minimum;
-  int max = queryctrl.maximum;
- 
-  //set value
-  struct v4l2_control control;
-  memset (&control, 0, sizeof (v4l2_control));
-  control.id = property;
-  if(xioctl (device,VIDIOC_G_CTRL, &control)==-1) return -1;
-  
-  return ((float)control.value - min + 1) / (max - min);
-}
-
-void V4LCamera::SetProperty(int property,float value) {
-  //get min and max value
-  struct v4l2_queryctrl queryctrl;
-  queryctrl.id = property;
-  if(xioctl (device, VIDIOC_QUERYCTRL,&queryctrl)==-1) {
-    Thread::Warn("prop %x, VIDIOC_QUERYCTRL failed\n",property);
-  }
-  int min = queryctrl.minimum;
-  int max = queryctrl.maximum;
- 
-  //set value
-  struct v4l2_control control;
-  memset (&control, 0, sizeof (v4l2_control));
-  control.id = property;
-  control.value = (int)(value * (max - min) + min);
-  if(xioctl (device,VIDIOC_S_CTRL, &control)==-1) {
-    Thread::Warn("prop %x, VIDIOC_S_CTRL failed\n",property);
-  }
-}
-
-int V4LCamera::xioctl( int fd, int request, void *arg) {
-  int r;
-
-  do r = ioctl (fd, request, arg);
-  while (-1 == r && EINTR == errno);
-
-  return r;
+  pimpl_->SetContrast(value);
 }
 
Index: /trunk/lib/FlairSensorActuator/src/V4LCamera.h
===================================================================
--- /trunk/lib/FlairSensorActuator/src/V4LCamera.h	(revision 351)
+++ /trunk/lib/FlairSensorActuator/src/V4LCamera.h	(revision 352)
@@ -11,12 +11,9 @@
  */
 
-#ifndef V4LCamera_H
-#define V4LCamera_H
+#ifndef V4LCAMERA_H
+#define V4LCAMERA_H
 
 #include <Thread.h>
 #include "Camera.h"
-
-#include <linux/videodev2.h>
-#define DEFAULT_V4L_BUFFERS 4
 
 namespace flair {
@@ -24,10 +21,7 @@
     class Image;
   }
-  namespace gui {
-    class DoubleSpinBox;
-    class CheckBox;
-    class Label;
-  }
 }
+
+class V4LCamera_impl;
 
 namespace flair {
@@ -38,4 +32,5 @@
 */
 class V4LCamera : public core::Thread, public Camera {
+  friend class ::V4LCamera_impl;
 public:
   /*!
@@ -141,28 +136,7 @@
   void Run(void);
   
-  gui::Tab *sensor_tab;
-  gui::DoubleSpinBox *bright, *exposure, *gain, *contrast, *hue, *sharpness,*sat;
-  gui::CheckBox *autogain, *awb, *autoexposure;
-  gui::Label *fps;
-  
-  int device;
-  bool hasProblems;
-  void* buffers[DEFAULT_V4L_BUFFERS];
-  int nbBuffers;
-  char *imageData;
-  bool useMemoryUsrPtr;
-  
-  int Init(int width, int height,unsigned long colorspace);
-  int xioctl( int fd, int request, void *arg);
-  void SetProperty(int property,float value);
-  float GetProperty(int property);
-  int GrabFrame(void);
-  int AllocV4LBuffers(void);
-  int AllocUserBuffers(void);
-  int QueueBuffer(int index);
-  int QueueBuffer(struct v4l2_buffer *buf);
-  struct v4l2_buffer dQueuedBuffer;
+  class V4LCamera_impl *pimpl_;
 };
 } // end namespace sensor
 } // end namespace flair
-#endif // V4LCamera_H
+#endif // V4LCAMERA_H
Index: /trunk/lib/FlairSensorActuator/src/V4LCamera_impl.cpp
===================================================================
--- /trunk/lib/FlairSensorActuator/src/V4LCamera_impl.cpp	(revision 352)
+++ /trunk/lib/FlairSensorActuator/src/V4LCamera_impl.cpp	(revision 352)
@@ -0,0 +1,504 @@
+// %flair:license{
+// This file is part of the Flair framework distributed under the
+// CECILL-C License, Version 1.0.
+// %flair:license}
+//  created:    2014/07/17
+//  filename:   V4LCamera_impl.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    base class for V4l camera
+//
+//
+/*********************************************************************/
+
+#include "V4LCamera_impl.h"
+#include "V4LCamera.h"
+#include <GroupBox.h>
+#include <DoubleSpinBox.h>
+#include <CheckBox.h>
+#include <Label.h>
+#include <Image.h>
+#include <FrameworkManager.h>
+#include <fcntl.h>
+//#include <linux/videodev2.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <cstring>
+#include <sys/mman.h>
+#include <VisionFilter.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::sensor;
+
+  
+V4LCamera_impl::V4LCamera_impl(V4LCamera *self,string name,uint8_t camera_index, uint16_t width, uint16_t height,
+                     Image::Type::Format format) {
+  this->self=self;
+  
+  string deviceName="/dev/video"+std::to_string(camera_index);
+  device = open(deviceName.c_str(), O_RDWR | O_NONBLOCK);
+  if (device == -1) {
+      ((Thread*)self)->Err("Cannot open %s\n",deviceName.c_str());
+  } else {
+      Printf("V4LCamera %s, opened %s\n",name.c_str(),deviceName.c_str());
+  }
+
+  if(format == Image::Type::Format::UYVY) {
+    if(Init(width,height,V4L2_PIX_FMT_UYVY) == -1) {
+     ((Thread*)self)->Err("initialisation failed\n");
+    }
+  } else if (format == Image::Type::Format::YUYV) {
+    if(Init(width,height,V4L2_PIX_FMT_YUYV) == -1) {
+     ((Thread*)self)->Err("initialisation failed\n");
+    }
+  } else {
+    ((Thread*)self)->Err("format not supported\n");
+  }
+  
+  //todo: better handling of detection, only neeeded for omap/dm
+  //also in run, copy from v4l to cmem is not necessary if not using cmem...
+#ifdef ARMV7A
+  useMemoryUsrPtr=true;
+#else
+  useMemoryUsrPtr=false;
+#endif
+  if(useMemoryUsrPtr) {
+    AllocUserBuffers();
+  } else {
+    AllocV4LBuffers();
+  }
+  
+  for (int i=0;i < nbBuffers;i++) {
+    QueueBuffer(i);
+  }
+
+  /* enable the streaming */
+  v4l2_buf_type type;
+  type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  if (-1 == xioctl (device, VIDIOC_STREAMON,&type)) {
+    ((Thread*)self)->Err("VIDIOC_STREAMON error\n");
+  }
+  
+  // ground station
+  gain = new DoubleSpinBox(self->GetGroupBox()->NewRow(), "gain:", 0, 1, 0.1);
+  exposure = new DoubleSpinBox(self->GetGroupBox()->LastRowLastCol(), "exposure:", 0,1, 0.1);
+  bright = new DoubleSpinBox(self->GetGroupBox()->LastRowLastCol(), "bright:", 0, 1, 0.1);
+  contrast = new DoubleSpinBox(self->GetGroupBox()->LastRowLastCol(), "contrast:", 0,1, 0.1);
+  hue = new DoubleSpinBox(self->GetGroupBox()->LastRowLastCol(), "hue:", 0, 1, 0.1);
+  sharpness = new DoubleSpinBox(self->GetGroupBox()->LastRowLastCol(), "sharpness:", 0, 1, 0.1);
+  sat = new DoubleSpinBox(self->GetGroupBox()->LastRowLastCol(), "saturation:", 0, 1,0.1);
+  autogain = new CheckBox(self->GetGroupBox()->NewRow(), "autogain:");
+  autoexposure = new CheckBox(self->GetGroupBox()->LastRowLastCol(), "autoexposure:");
+  awb = new CheckBox(self->GetGroupBox()->LastRowLastCol(), "awb:");
+  fps = new Label(self->GetGroupBox()->NewRow(), "fps");
+  
+  hasProblems=false;
+}
+
+V4LCamera_impl::~V4LCamera_impl() {
+  if(useMemoryUsrPtr) {
+    for (int i = 0; i < nbBuffers; i++) {
+      FreeFunction((char*)buffers[i]);
+    }
+  } else {
+      FreeFunction(imageData);
+  }
+  close(device);
+}
+
+int V4LCamera_impl::Init(int width, int height,unsigned long colorspace) {
+  struct v4l2_capability cap;
+  memset(&cap, 0, sizeof (v4l2_capability));
+  
+  if(-1 == xioctl(device, VIDIOC_QUERYCAP, &cap)) {
+    return -1;
+  }
+     
+  if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {
+    ((Thread*)self)->Err("device is unable to capture video memory.\n");
+    return -1;
+  }
+
+  struct v4l2_format form;
+  memset(&form, 0, sizeof (v4l2_format));
+  form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+  /* read the current setting */
+  if(-1 == xioctl(device, VIDIOC_G_FMT, &form)) {
+   ((Thread*)self)->Err("Could not obtain specifics of capture window.\n");
+   return -1;
+  }
+
+  /* set the values we want to change */
+  form.fmt.pix.width = width; 
+  form.fmt.pix.height = height;
+  form.fmt.win.chromakey = 0;
+  form.fmt.win.field = V4L2_FIELD_ANY;
+  form.fmt.win.clips = 0;
+  form.fmt.win.clipcount = 0;
+  form.fmt.pix.field = V4L2_FIELD_ANY;
+  form.fmt.pix.pixelformat = colorspace;
+
+  /* ask the device to change the size*/
+  if(-1 == xioctl (device, VIDIOC_S_FMT, &form)) {
+    ((Thread*)self)->Err("Could not set specifics of capture window.\n");
+    return -1;
+  }
+  
+  return 0;
+}
+
+int V4LCamera_impl::AllocV4LBuffers() {
+  struct v4l2_requestbuffers req;
+  memset(&req, 0, sizeof (v4l2_requestbuffers));
+  nbBuffers=DEFAULT_V4L_BUFFERS;
+
+  try_again:
+
+  req.count = nbBuffers;
+  req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  req.memory = V4L2_MEMORY_MMAP;
+
+  if(-1 == xioctl(device, VIDIOC_REQBUFS, &req)) {
+    if (EINVAL == errno) {
+      ((Thread*)self)->Err("camera does not support memory mapping\n");
+    } else {
+      ((Thread*)self)->Err("VIDIOC_REQBUFS failed\n");
+    }
+    return -1;
+  }
+
+  if(req.count < nbBuffers) {
+    if (nbBuffers == 1) {
+      ((Thread*)self)->Err("Insufficient buffer memory\n");
+      return -1;
+    } else {
+      nbBuffers--;
+      ((Thread*)self)->Warn("Insufficient buffer memory -- decreaseing buffers to %i\n",nbBuffers);
+      goto try_again;
+    }
+  }
+
+  for(int i=0; i<req.count; i++) {
+    struct v4l2_buffer buf;
+    memset(&buf, 0, sizeof (v4l2_buffer));
+
+    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    buf.memory = V4L2_MEMORY_MMAP;
+    buf.index = i;
+
+    if(-1 == xioctl(device, VIDIOC_QUERYBUF, &buf)) {
+      ((Thread*)self)->Err("VIDIOC_QUERYBUF error\n");
+      return -1;
+    }
+
+    if(self->output->GetDataType().GetSize()!=buf.length) {
+      ((Thread*)self)->Err("buf size is not as exepcted %i/%i\n",buf.length,self->output->GetDataType().GetSize());
+      return -1;
+    }
+
+    buffers[i]=mmap(NULL,buf.length,PROT_READ | PROT_WRITE,MAP_SHARED,device, buf.m.offset);
+
+    if(MAP_FAILED == buffers[i]) {
+      ((Thread*)self)->Err("mmap error\n");
+      return -1;
+    }
+  }
+
+  //allocate output data
+  imageData = AllocFunction(self->output->GetDataType().GetSize());
+  //Printf("cmem allocated %i at %x\n",output->GetDataType().GetSize(),imageData);
+
+  return 1;
+};
+
+int V4LCamera_impl::AllocUserBuffers(void) {
+  struct v4l2_requestbuffers req;
+  memset(&req, 0, sizeof (v4l2_requestbuffers));
+  nbBuffers=DEFAULT_V4L_BUFFERS;
+
+  req.count = nbBuffers;
+  req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  req.memory = V4L2_MEMORY_USERPTR;
+
+  if (xioctl (device, VIDIOC_REQBUFS, &req)==-1) {
+    if (errno==EINVAL) {
+      ((Thread*)self)->Err("VIDIOC_REQBUFS user memory not supported\n");
+    } else {
+      ((Thread*)self)->Err ("VIDIOC_REQBUFS xioctl\n");
+    }
+    return -1;
+  }
+
+  for (int i=0; i<nbBuffers; i++) {
+    buffers[i] =AllocFunction(self->output->GetDataType().GetSize());
+  }
+
+  return 1;
+};
+
+int V4LCamera_impl::GrabFrame(void) {
+  fd_set fds;
+  struct timeval tv;
+  FD_ZERO (&fds);
+  FD_SET (device, &fds);
+
+  tv.tv_sec = 0;
+  tv.tv_usec = 100000;
+
+  int r=select(device+1, &fds, NULL, NULL, &tv);
+
+  if (r==-1) {
+    char errorMsg[256];
+    ((Thread*)self)->Err("select (%s)\n", strerror_r(-r, errorMsg, sizeof(errorMsg)));
+    return -1;
+  }
+
+  if (r==0) {
+    ((Thread*)self)->Err("select timeout\n");
+    return -1;
+  }
+  
+  struct v4l2_buffer buf;
+  memset(&buf, 0, sizeof (v4l2_buffer));
+  buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  if(useMemoryUsrPtr) {
+    buf.memory=V4L2_MEMORY_USERPTR;
+  } else {
+    buf.memory=V4L2_MEMORY_MMAP;
+  }
+
+   //get last captured buffer
+  dQueuedBuffer.index=-1;
+  for(int i=0;i<nbBuffers;i++) {
+    if (xioctl (device, VIDIOC_DQBUF, &buf)==-1) {
+      if (errno==EAGAIN) {//when no new buffer is available for reading (non blocking)
+        //Printf("%s eagain\n",((Thread*)self)->ObjectName().c_str());
+        break;
+      } else {
+        ((Thread*)self)->Err("VIDIOC_DQBUF xioctl\n");
+        return -1;
+      }
+    } else {
+      //Printf("%s %i dqueued\n",((Thread*)self)->ObjectName().c_str(),buf.index);
+      //Printf("%i %x %i %i\n",buf.bytesused,buf.flags,buf.field,buf.sequence);
+      if(dQueuedBuffer.index!=-1) {
+        //Printf("%s %i queued\n",((Thread*)self)->ObjectName().c_str(),dQueuedBuffer.index);
+        QueueBuffer(&dQueuedBuffer);
+      }
+      dQueuedBuffer=buf;
+    }
+  }
+  //Printf("%s %i\n",((Thread*)self)->ObjectName().c_str(),dQueuedBuffer.index);
+
+  return 1;
+}
+
+void V4LCamera_impl::Run(void) {
+  Time cam_time, new_time, fpsNow, fpsPrev;
+  int fpsCounter = 0;
+
+  cam_time = GetTime();
+  fpsPrev = cam_time;
+
+  while (!self->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)
+      self->SetGain(gain->Value());
+    if (exposure->ValueChanged() == true && autoexposure->Value() == false)
+      self->SetExposure(exposure->Value());
+    if (bright->ValueChanged() == true)
+      self->SetBrightness(bright->Value());
+    if (sat->ValueChanged() == true)
+      self->SetSaturation(sat->Value());
+    if (contrast->ValueChanged() == true)
+      self->SetContrast(contrast->Value());
+    if (hue->ValueChanged() == true)
+      self->SetHue(hue->Value());
+    //if (sharpness->ValueChanged() == true)
+    //  cvSetCaptureProperty(capture, CV_CAP_PROP_SHARPNESS, sharpness->Value());
+    if (autogain->ValueChanged() == true) {
+      self->SetAutoGain(autogain->Value());
+      if (autogain->Value() == true) {
+        gain->setEnabled(false);
+      } else {
+        gain->setEnabled(true);
+        self->SetGain(gain->Value());
+      }
+    }
+    if (autoexposure->ValueChanged() == true) {
+      self->SetAutoExposure(autoexposure->Value());
+      if (autoexposure->Value() == true) {
+        exposure->setEnabled(false);
+      } else {
+        exposure->setEnabled(true);
+        self->SetExposure(exposure->Value());
+      }
+    }
+    //if (awb->ValueChanged() == true)
+    //  cvSetCaptureProperty(capture, CV_CAP_PROP_AWB, awb->Value());
+   
+    // cam pictures
+    if (!GrabFrame()) {
+      Printf("Could not grab a frame\n");
+    }
+        
+    //check for ps3eye deconnection in hds uav
+    new_time = GetTime();
+    if(new_time-cam_time>100*1000*1000) {
+      ((Thread*)self)->Warn("delta t trop grand\n");
+      hasProblems=true;
+    }/*
+    if(hasProblems==false) {
+      struct v4l2_format form;
+      form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+      xioctl(device, VIDIOC_G_FMT,&form);
+      if(xioctl (device, VIDIOC_G_FMT,&form)<0) {
+        ((Thread*)self)->Warn("camera disconnected\n");
+        hasProblems=true;
+      }
+    }*/
+
+    //select buffer
+    if(useMemoryUsrPtr) {//buffers are already in CMEM
+      imageData=(char*)buffers[dQueuedBuffer.index];
+      //dequeue it latter (buffer used by ProcessUpdate)
+    } else {//copy to CMEM allocated buffer 
+      memcpy(imageData,(char *)buffers[dQueuedBuffer.index],self->output->GetDataType().GetSize());
+      QueueBuffer(&dQueuedBuffer);//we can do it right now
+    }
+    
+    self->output->GetMutex();
+    self->output->buffer=imageData;
+    self->output->ReleaseMutex();
+   
+    self->output->SetDataTime(cam_time);
+    self->ProcessUpdate(self->output);
+    cam_time = new_time;
+    
+    if(useMemoryUsrPtr) {
+      QueueBuffer(&dQueuedBuffer);//now it is possible to dequeue
+    }
+  }
+}
+
+int V4LCamera_impl::QueueBuffer(struct v4l2_buffer *buf) {
+  if(buf->index>=0 && buf->index<nbBuffers) {
+    int ret=xioctl (device, VIDIOC_QBUF,buf);
+    if (ret==-1) {
+      ((Thread*)self)->Err("VIDIOC_QBUF xioctl %s\n",strerror(-ret));
+      return -1;
+    }
+  }
+  return 0;
+}
+
+int V4LCamera_impl::QueueBuffer(int index) {
+  struct v4l2_buffer buf;
+  memset(&buf, 0, sizeof (v4l2_buffer));
+  
+  buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  buf.index=(unsigned long)index;
+  if(useMemoryUsrPtr) {
+    buf.memory=V4L2_MEMORY_USERPTR;
+    buf.m.userptr=(unsigned long)(buffers[index]);
+    buf.length=self->output->GetDataType().GetSize();
+  } else {
+    buf.memory=V4L2_MEMORY_MMAP;
+  }
+  return QueueBuffer(&buf);
+}
+
+void V4LCamera_impl::SetAutoGain(bool value) {
+  SetProperty(V4L2_CID_AUTOGAIN, value);
+}
+
+void V4LCamera_impl::SetAutoExposure(bool value) {
+  ((Thread*)self)->Warn("not implemented\n");
+}
+
+void V4LCamera_impl::SetGain(float value) {
+  SetProperty(V4L2_CID_GAIN, value);
+}
+
+void V4LCamera_impl::SetExposure(float value) {
+  SetProperty(V4L2_CID_EXPOSURE, value);
+}
+
+void V4LCamera_impl::SetBrightness(float value) {
+  SetProperty(V4L2_CID_BRIGHTNESS, value);
+}
+
+void V4LCamera_impl::SetSaturation(float value) {
+  SetProperty(V4L2_CID_SATURATION, value);
+}
+
+void V4LCamera_impl::SetHue(float value) {
+  SetProperty(V4L2_CID_HUE, value);
+}
+
+void V4LCamera_impl::SetContrast(float value) {
+  SetProperty(V4L2_CID_CONTRAST, value);
+}
+
+float V4LCamera_impl::GetProperty(int property) {
+  //get min and max value
+  struct v4l2_queryctrl queryctrl;
+  queryctrl.id = property;
+  if(xioctl (device, VIDIOC_QUERYCTRL,&queryctrl)==-1) return -1;
+  int min = queryctrl.minimum;
+  int max = queryctrl.maximum;
+ 
+  //set value
+  struct v4l2_control control;
+  memset (&control, 0, sizeof (v4l2_control));
+  control.id = property;
+  if(xioctl (device,VIDIOC_G_CTRL, &control)==-1) return -1;
+  
+  return ((float)control.value - min + 1) / (max - min);
+}
+
+void V4LCamera_impl::SetProperty(int property,float value) {
+  //get min and max value
+  struct v4l2_queryctrl queryctrl;
+  queryctrl.id = property;
+  if(xioctl (device, VIDIOC_QUERYCTRL,&queryctrl)==-1) {
+    ((Thread*)self)->Warn("prop %x, VIDIOC_QUERYCTRL failed\n",property);
+  }
+  int min = queryctrl.minimum;
+  int max = queryctrl.maximum;
+ 
+  //set value
+  struct v4l2_control control;
+  memset (&control, 0, sizeof (v4l2_control));
+  control.id = property;
+  control.value = (int)(value * (max - min) + min);
+  if(xioctl (device,VIDIOC_S_CTRL, &control)==-1) {
+    ((Thread*)self)->Warn("prop %x, VIDIOC_S_CTRL failed\n",property);
+  }
+}
+
+int V4LCamera_impl::xioctl( int fd, int request, void *arg) {
+  int r;
+
+  do r = ioctl (fd, request, arg);
+  while (-1 == r && EINTR == errno);
+
+  return r;
+}
Index: /trunk/lib/FlairSensorActuator/src/unexported/V4LCamera_impl.h
===================================================================
--- /trunk/lib/FlairSensorActuator/src/unexported/V4LCamera_impl.h	(revision 352)
+++ /trunk/lib/FlairSensorActuator/src/unexported/V4LCamera_impl.h	(revision 352)
@@ -0,0 +1,152 @@
+// %flair:license{
+// This file is part of the Flair framework distributed under the
+// CECILL-C License, Version 1.0.
+// %flair:license}
+/*!
+ * \file V4LCamera.h
+ * \brief Base class for V4l camera
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2014/07/17
+ * \version 4.0
+ */
+
+#ifndef V4LCAMERA_IMPL_H
+#define V4LCAMERA_IMPL_H
+
+#include "V4LCamera.h"
+#include <linux/videodev2.h>
+
+#define DEFAULT_V4L_BUFFERS 4
+
+namespace flair {
+  namespace core {
+    class Image;
+  }
+  namespace gui {
+    class DoubleSpinBox;
+    class CheckBox;
+    class Label;
+  }
+}
+
+
+/*! \class V4LCamera_impl
+*
+* \brief Base class for V4l camera
+*/
+class V4LCamera_impl {
+public:
+  /*!
+  * \brief Constructor
+  *
+  * Construct a Camera.
+	* It will be child of the FrameworkManager.
+  *
+  * \param name name
+  * \param camera_index camera index
+  * \param width width
+  * \param height height
+  * \param format image format
+  */
+  V4LCamera_impl(flair::sensor::V4LCamera *self,std::string name,
+            uint8_t camera_index, uint16_t width, uint16_t height,
+            flair::core::Image::Type::Format format);
+
+  /*!
+  * \brief Destructor
+  *
+  */
+  ~V4LCamera_impl();
+  
+  /*!
+  * \brief Run function
+  *
+  */
+  void Run(void);
+  
+  bool hasProblems;
+  
+  /*!
+  * \brief Set Gain
+  *
+  * \param value value between 0 and 1
+  */
+  void SetGain(float value);
+
+  /*!
+  * \brief Set Auto Gain
+  *
+  * \param value value
+  */
+  void SetAutoGain(bool value);
+
+  /*!
+  * \brief Set Exposure
+  *
+  * \param value value between 0 and 1
+  */
+  void SetExposure(float value);
+
+  /*!
+  * \brief Set Auto Exposure
+  *
+  * \param value value
+  */
+  void SetAutoExposure(bool value);
+
+  /*!
+  * \brief Set Brightness
+  *
+  * \param value value between 0 and 1
+  */
+  void SetBrightness(float value);
+
+  /*!
+  * \brief Set Saturation
+  *
+  * \param value value between 0 and 1
+  */
+  void SetSaturation(float value);
+
+  /*!
+  * \brief Set Hue
+  *
+  * \param value value between 0 and 1
+  */
+  void SetHue(float value);
+
+  /*!
+  * \brief Set Contrast
+  *
+  * \param value value between 0 and 1
+  */
+  void SetContrast(float value);
+  
+private:
+ 
+  flair::sensor::V4LCamera *self;
+  flair::gui::Tab *sensor_tab;
+  flair::gui::DoubleSpinBox *bright, *exposure, *gain, *contrast, *hue, *sharpness,*sat;
+  flair::gui::CheckBox *autogain, *awb, *autoexposure;
+  flair::gui::Label *fps;
+  
+  int device;
+  
+  void* buffers[DEFAULT_V4L_BUFFERS];
+  int nbBuffers;
+  char *imageData;
+  bool useMemoryUsrPtr;
+  
+  int Init(int width, int height,unsigned long colorspace);
+  int xioctl( int fd, int request, void *arg);
+  void SetProperty(int property,float value);
+  float GetProperty(int property);
+  int GrabFrame(void);
+  int AllocV4LBuffers(void);
+  int AllocUserBuffers(void);
+  int QueueBuffer(int index);
+  int QueueBuffer(struct v4l2_buffer *buf);
+  struct v4l2_buffer dQueuedBuffer;
+};
+
+#endif // V4LCAMERA_IMPL_H
